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可以,因此有的题目用贪心是错的
原文地址:https://www.cnblogs.com/1994two/p/3060939.html