用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可以,因此有的题目用贪心是错的