上一页 1 ··· 4 5 6 7 8 9 10 11 12 ··· 27 下一页
摘要: 首先推一篇文章,写的很清楚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 阅读全文
posted @ 2013-08-08 17:19 执着追求的IT小小鸟 阅读(210) 评论(0) 推荐(0) 编辑
摘要: 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 ... 阅读全文
posted @ 2013-08-08 15:51 执着追求的IT小小鸟 阅读(147) 评论(0) 推荐(0) 编辑
摘要: 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 阅读全文
posted @ 2013-08-08 11:24 执着追求的IT小小鸟 阅读(294) 评论(0) 推荐(0) 编辑
摘要: http://acm.hdu.edu.cn/showproblem.php?pid=2571简单dp题目,推算最大的路径和:状态:f[i][j]:从第[i,j]到终点的最大值状态转移:f[i][j]=max{f[i+1][j],f[i][j+1],f[i][j*k](k>1)}初始值:f[n][m]=a[n][m];这是递归的思想,而在dp代码中写出来应该是递推的写法:状态转移:f[i][j]=a[i][j]+max{f[i-1][j],f[i][j-1],f[i][j/k](k>1)}这题关键应该在于初始化,为了保证第一行和第一列保留的都是他们原本的数字,可以在二维矩阵外面再多加 阅读全文
posted @ 2013-08-07 21:29 执着追求的IT小小鸟 阅读(250) 评论(0) 推荐(0) 编辑
摘要: http://acm.hdu.edu.cn/showproblem.php?pid=2602典型的01背包问题,用动态规划来解即可。用子问题定义状态:即f[i][v]表示前i件物品恰放入一个容量为v的背包可以获得的最大价值。则其状态转移方程便是: f[i][v]=max{f[i-1][v],f[i-1][v-c[i]]+w[i]} 这个方程非常重要,基本上所有跟背包相关的问题的方程都是由它衍生出来的。所以有必要将它详细解释一下:“将前i件物品放入容量为v的背包中”这个子问题,若只考虑第i件物品的策略(放或不放),那么就可以转化为一个只牵扯前i-1件物品的问题。如果不放第i件物品,那么问题就转化 阅读全文
posted @ 2013-08-07 17:17 执着追求的IT小小鸟 阅读(348) 评论(0) 推荐(0) 编辑
摘要: http://acm.hdu.edu.cn/showproblem.php?pid=1513给一个字符串,求这个字符串最少增加几个字符能变成回文,如Ab3bd可以增加2个字符变为回文:Adb3bdA。通过这样的结论可以和最长公共子串联系起来(未证明):S和S' (注:S'是S的反串)的最长公共子串其实一定是回文的。这样我们就可以借助lcs来解决该题,即用s的长度减去lcs的值即可。#include #include short ans[2][5001];int max(int a,int b){ return a>b?a:b;} int main(){ int i,j,l 阅读全文
posted @ 2013-08-07 11:35 执着追求的IT小小鸟 阅读(162) 评论(0) 推荐(0) 编辑
摘要: dp过程当中由于递推的方式,经常要的只是最后的一个数据而已,所以前面算出来的数据可放弃,这样可以极大的节省空间,于是有这么一个方法滚动数组举个简单的例子:int d[]=new int[100];d[0]=1;d[1]=1;for(int i=2;i<100;i++)d[i]=d[i-1]+d[i-2];System.out.printf("%d",d[99]);上面这个循环d[i]只需要解集中的前2个解d[i-1]和d[i-2]; 为了节约空间用滚动数组的方法int d[]=new int[3]; d[0]=1;d[1]=1; for(int i=2;i<10 阅读全文
posted @ 2013-08-07 11:28 执着追求的IT小小鸟 阅读(183) 评论(0) 推荐(0) 编辑
摘要: http://poj.org/problem?id=2081要的就是存储中间数据的思想,避免重复计算Source CodeProblem: 2081 User: 297752873/*Memory: 41280K Time: 32MSLanguage: C Result: AcceptedSource Code*/#include#include int a[500001],hash[10000000];int main(){ int i,k; memset(hash,0,sizeof(hash)); a[0]=0;hash[0... 阅读全文
posted @ 2013-08-07 09:46 执着追求的IT小小鸟 阅读(116) 评论(0) 推荐(0) 编辑
摘要: http://poj.org/problem?id=1163因为要求的是最大的路径和,那就开个数组存储,然后从倒数第二行开始计算,每条路径上要保留左右子树上的最大数再加上本身的数,然后保留在本身结点位置,可避免重复计算转移方程num(i,j)=max(num(i+1,j),num(i+1,j+1))+num(i,j);#includeint max(int a,int b){ return a>b?a:b;}int main(){ int num[101][101],sum,i,j; scanf("%d",&sum); for(i=0;i=0;i--) ... 阅读全文
posted @ 2013-08-06 21:18 执着追求的IT小小鸟 阅读(141) 评论(0) 推荐(0) 编辑
摘要: http://acm.hdu.edu.cn/showproblem.php?pid=1331dp打表就是这么个过程了 1 #include 2 #include 3 int main() 4 { 5 int i,j,k,a,b,c; 6 int w[21][21][21]; 7 for(i=0;i20||b>20||c>20)k=w[20][20][20];19 else k=w[a][b][c];20 printf("w(%d, %d, %d) = %d\n",a,b,c,k);21 }22 return 0;23 } Vi... 阅读全文
posted @ 2013-08-06 20:42 执着追求的IT小小鸟 阅读(171) 评论(0) 推荐(0) 编辑
上一页 1 ··· 4 5 6 7 8 9 10 11 12 ··· 27 下一页