poj 1837 Balance

下面是个人一开始菜菜的想法。。估计以后回来看会很可笑:
一开始先把总状态忘右边移7500,保护数组。。

flag1[0][7500]=1;
int ans=0;
for(i=1;i<=m;i++)
    for(j=15000;j>=0;j--)
        if(flag1[i-1][j]==1)
          for(k=1;k<=n;k++)
           { dp[i][j+w[i]*l[k]]=dp[i-1][j]+w[i]*l[k]; flag1[i][j+w[i]*l[k]]=1; if(i==m&&dp[i][j+w[i]*l[k]]==0) ans++; }

没有考虑j+w[i]*l[k]的重复。。,应该就是这里错了,所以要把重复的情况考虑进去。。
如果是另外的错误,希望大家指出来。。谢谢!

想了一下午+。。
没出来。。
这里面加法和乘法搞得乱糟糟的。。
于是dp保存的是重量的话,我不会了。。
在看了别人的题解后恍然大悟
dp保存的是某种状态的数目。。。完美解绝了上面的问题
而且自己的flag数组也有往这方面考虑。。
要是当时再想想或许就自己出来了。。
还有,下面的代码是G++。。

#include <stdio.h>
#include <string.h>
int main()
{
    int n,m;
    int w[20],l[20];
    int i,j,k;
    scanf("%d%d",&n,&m);
    for(i=1;i<=n;i++)
        scanf("%d",&l[i]);
    for(i=1;i<=m;i++)
        scanf("%d",&w[i]);
    int dp[20][15000];
    memset(dp,0,sizeof(dp));
    dp[0][7500]=1;//此时为初始状态,只有1种情况。。
    for(i=1;i<=m;i++)
        for(j=0;j<=15000;j++)//从0还是15000无所谓啦,因为是状态总数
           if(dp[i-1][j]>0)
              for(k=1;k<=n;k++)
                  dp[i][j+w[i]*l[k]]+=dp[i-1][j];//dp数组记录的是从头开始到目前有几种情况。。
    printf("%d\n",dp[m][7500]);
return 0;
}

你可能感兴趣的:(dp,poj)