POJ 3132 Sum of Different Primes (DP)

题意:给定n和k,要求找出k个互不相同的素数,使其和==n,求这样的组合有多少中

思路:因为素数互不相同,自然想到了0-1背包,可是怎么背包却想了很久,因为多了一个限制:k,那么必须用两维数组来做,用dp[M][K]表示在组成M时,K个素数互不相同的情况,于是可以用0-1背包来对每个prime进行dp:

  dp[m][k] = dp[m][k] + dp[m-prime[i]][k-1]; //注意数组不要越界

写完后发现代码运行需要500ms,别人的都是1xms,怎么差别这么大?看了别人的思路和自己的差不多,可是问什么时间差这么多呢?希望路过的神牛指点一二。

#include <iostream>
#include
<cstdio>
#include
<algorithm>
#include
<memory.h>
#include
<cmath>
#include
<set>
#include
<bitset>
#include
<vector>
using namespace std;

const int BORDER = (1<<20)-1;
const int MAXSIZE = 37;
const int MAXN = 1250;
const int INF = 0x7ffffff;
#define CLR(x,y) memset(x,y,sizeof(x))

int n,ans,k,index;
int prime[MAXN],arr_dp[MAXN][MAXN];
int init()
{
CLR(arr_dp,
0);
arr_dp[
0][0] = 1;
return 0;
}
bool _prime(const int& num)
{
int tmp = (int)sqrt(float(num))+1;
for(int i = 2; i < tmp; ++i)
if(!(num%i))
return false;
return true;
}
int find_prime()
{
int i,j;
index
= 0;
for(i = 2; i <= 1120; ++i)
if(_prime(i))
prime[index
++] = i;
return 0;
}
int dp()
{
int bor = index;
for(int i = 0; i < index; ++i)
if(prime[i] > n)
{
bor
= i;
break;
}
for( int i = 0; i < bor; ++i)
for(int j = n; j >= prime[i]; --j)
for(int h = k; h >= 1; --h)
arr_dp[j][h]
+= arr_dp[j-prime[i]][h-1];
OUT(arr_dp[n][k]);
return 0;
}
int main()
{
int i,j,tmp;
find_prime();
while(scanf("%d%d",&n,&k))
{
if(!n && !k)
break;
init();
dp();
}
return 0;
}

原文地址:https://www.cnblogs.com/lvpengms/p/1708787.html