刚学记忆化,用这道做过的题练手。 AC代码:
#include <iostream>
#include <cstring>
using namespace std;
int a[21],f[25][25],n,k,sum=0;
bool is[21];
bool isPrime(int n)
{
if(n<=1)
return false;
for(int i=2;i*i<=n;i++)
if(n%i==0)
return false;
return true;
}
int dfs(int begin,int m)
{
int ans=0;
//if(f[begin][m]!=-1)
// return f[begin][m];
if(m==k)
{
if(isPrime(sum))
ans++;
}
for(int i=begin;i<=n;i++)
if(!is[i])
{
sum+=a[i];
is[i]=true;
ans+=dfs(i+1,m+1);
sum-=a[i];
is[i]=false;
}
//f[begin][m]=ans;
return ans;
}
int main()
{
memset(f,-1,sizeof(f));
scanf("%d%d",&n,&k);
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
printf("%d\n",dfs(1,0));
return 0;
}
记忆化代码,样例没过,如下:
#include <iostream>
#include <cstring>
using namespace std;
int a[21],f[25][25],n,k,sum=0;
bool is[21];
bool isPrime(int n)
{
if(n<=1)
return false;
for(int i=2;i*i<=n;i++)
if(n%i==0)
return false;
return true;
}
int dfs(int begin,int m)
{
int ans=0;
if(f[begin][m]!=-1)
return f[begin][m];
if(m==k)
{
if(isPrime(sum))
ans++;
}
for(int i=begin;i<=n;i++)
if(!is[i])
{
sum+=a[i];
is[i]=true;
ans+=dfs(i+1,m+1);
sum-=a[i];
is[i]=false;
}
f[begin][m]=ans;
return ans;
}
int main()
{
memset(f,-1,sizeof(f));
scanf("%d%d",&n,&k);
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
printf("%d\n",dfs(1,0));
return 0;
}