poj(1837)(完全背包)
用dp[i][j]表示放入i种物品的时候平衡数为j,由于此处左右两边分了正负数,而数组是没有正负的,因此将中间点7500看做平衡点 #include <iostream> #include <cstdio> #include <string.h> using namespace std; int dp[25][15005]; int main() { int i,j,c,g,v,sum,a[999],b[999]; while(scanf("%d%d",&c,&g)!=EOF) { memset(dp,0,sizeof(dp)); for (i=1;i<=c;++i) scanf("%d",&a[i]);//代表位置 for (j=1;j<=g;++j) scanf("%d",&b[j]);//代表重量 dp[0][7500]=1;//放入0个物品时,就已经是平衡点 for (i=1;i<=g;++i) for (j=1;j<=c;++j) for (v=0;v<=15000;++v) dp[i][v]=dp[i][v]+dp[i-1][v-b[i]*a[j]];//表示这个状态的方法数=先前得到的方法数+上个状态的方法数 printf ("%d\n",dp[g][7500]); } return 0; } 可以将此题看做完全背包,其中重量即是物品的种类,而位置可以放多个物品,因此看做物品的个数 注意区分完全背包于01 背包,01背包由于最多只能取一个,因此计算时是倒着的
用贪心有时不能完全充分利用空间,但用dp可以,因此有的题目用贪心是错的