poj 1837 Balance
2016-02-21 18:52
302 查看
下面是个人一开始菜菜的想法。。估计以后回来看会很可笑:
一开始先把总状态忘右边移7500,保护数组。。
没有考虑j+w[i]*l[k]的重复。。,应该就是这里错了,所以要把重复的情况考虑进去。。
如果是另外的错误,希望大家指出来。。谢谢!
想了一下午+。。
没出来。。
这里面加法和乘法搞得乱糟糟的。。
于是dp保存的是重量的话,我不会了。。
在看了别人的题解后恍然大悟
dp保存的是某种状态的数目。。。完美解绝了上面的问题
而且自己的flag数组也有往这方面考虑。。
要是当时再想想或许就自己出来了。。
还有,下面的代码是G++。。
一开始先把总状态忘右边移7500,保护数组。。
[code]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++。。
[code]#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; }