摘要:
首先推一篇文章,写的很清楚http://blog.sina.com.cn/s/blog_8627bf080100t9wv.html理解:在01背包问题当中,内循环用的是逆序,由方程f[v]=max(f[v],f[v-ci]+wi),假定前面的式子都是正确的,那么当我们在推f[j]的时候,进行比较的f[j]和f[j-ci]两者里面保存的必然就是前一状态遗留下来的结果,这样可以一直满足状态转移方程的成立,而至于边界问题是初始化的时候应该解决的void ZeroOnePack(){for(int i=1;i=weight[i];j--)DP[j]=DP[j]>DP[j-weight[i]]+v 阅读全文
摘要:
http://acm.hdu.edu.cn/showproblem.php?pid=2069原以为非得用dp。。。后来查了发现暴力就可以了,所以打个表62ms过了,dp完全背包努力中。。。 1 #include 2 int main() 3 { 4 int i,a,b,c,d,e,coin[300]={1},n; 5 for(i=1;i<=250;i++) 6 for(a=0;a<=i;a++) 7 for(b=0;5*b<=i-a;b++) 8 for(c=0;10*c<=i-a-5*b;c++) 9 ... 阅读全文
摘要:
http://acm.hdu.edu.cn/showproblem.php?pid=1203简单的01背包问题,与其他的区别在于,要利用“至少得到一份”的对立面的概率去计算,所以,要把每个概率变成1-x,然后求背包最小,记得+wi要改成*wi就可以了,其中还有一个初始化的问题,初始化为无穷大,而这里只需大于等于1就可以了,因为概率最大也就1,这样的比较最小时可以避免没有数值却依然被因为比较出来是最小而存数值进去的错误,这里可以用一维数组,或者滚动数组,两个版本都贴下 1 /*这里用的是滚动数组,时间46ms*/ 2 #include 3 #include 4 double dp[2][1000 阅读全文