摘要: 该题在选择物品的时候,必须得选择盒子,因此为有依赖的背包,注意与树形dp的区别#include <iostream>#include <cstdio>#include <string.h>using namespace std; int dp[55][100005];int main(){ int n,v,i,j,k,pi,t,c,w; while(scanf("%d%d",&n,&v)!=EOF) { memset(dp,0,sizeof(dp)); for (i=1;i<=n;++i) { scanf(" 阅读全文
posted @ 2013-05-10 15:24 一线添 阅读(252) 评论(0) 推荐(0) 编辑
摘要: #include <iostream>#include <cstdio>#include <string.h>WA了好多次,才发现动态转移方程有问题,这大概就是多个选择得到最优值吧此题类似多重背包,每组至少选一个,代码好乱哇using namespace std;int max(int a,int b){ if (a>b) return a; else return b;}struct node{ int k,cost,value;}s[1500];int dp[15][10005];int main(){ int n,k,v,i,j,l; while 阅读全文
posted @ 2013-05-09 14:06 一线添 阅读(117) 评论(0) 推荐(0) 编辑
摘要: 该题目为求01背包中的第k最优解: 开始时用dpp[i][j]表示用体积为i得到价值为j,WA了好多次,系统说是数组开的大小有问题 应该定义数组dp[i][j][k]表示前i个物品中用体积j所得价值排名第k,类似于dp[i][j], 该数组每次有两个方案可得,即dp[i-1][j][k]与dp[i-1][j-cost[i]][k]+value[i]; 用数组A及数组B分别保存数组dp[i-1][j][k]及数组dp[i-1][j-cost[i]][k]+value[i]的前k项, 再对两个数组进行合并,赋值给dp[i][j][k],不过知道最优是k优的一种特殊情况了,代码如下:#includ. 阅读全文
posted @ 2013-05-09 12:26 一线添 阅读(164) 评论(0) 推荐(0) 编辑
摘要: 该题为二维背包即比一维多加了一个限制条件,同理可以推至多维即是有多个限制条件#include <stdio.h>#include <string.h>struct node{ int r,e;}s[150];int max(int a,int b){ if (a>b) return a; else return b;}int main(){ int n,m,k,a,i,l,j,f[100][100]; while(scanf("%d%d%d%d",&n,&m,&k,&a)!=EOF) { for (i=1;i&l 阅读全文
posted @ 2013-05-06 19:24 一线添 阅读(131) 评论(0) 推荐(0) 编辑
摘要: 用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)); fo 阅读全文
posted @ 2013-05-05 14:16 一线添 阅读(360) 评论(0) 推荐(0) 编辑
摘要: 1;把每个石子的价值看做weight及cost,再抽象成dp模型,以便判断某个价值是否能通过组合得到 对多重背包的运算进行优化,采用二进制2:对于给定价值和相应价值的数量,判断某个价值能否取到,或者取到离该价值最近的价值,一般采用多重背包3:类似于hdu1059该题为判断某个价值能否取到,那么如果dp[i]=i,则可以取到,而对于poj1276要得到离i最近的那个价值,只需输出dp[i]即可,初始化全都为0, 还有另一种初始化方法,就是恰好取到(hdu1059)的题目全都初始化为inf,dp[0]=1,然后只需判断dp[i]是否大于0即可,对于(poj1276)则全都初始化为0hdu2844. 阅读全文
posted @ 2013-05-04 22:04 一线添 阅读(155) 评论(0) 推荐(0) 编辑
摘要: 参考自:http://blog.csdn.net/ice_crazy/article/details/7536332#include <iostream>#include <cstdio>#include <string.h>using namespace std;int n,s[999999],head[999999];int fun(){ int len,i,mid,l,r; memset(head,0,sizeof(head)); head[1]=s[1]; len=1; for (i=2;i<=n;++i)//采用二分查找 { l=1;... 阅读全文
posted @ 2013-05-02 22:30 一线添 阅读(130) 评论(0) 推荐(0) 编辑
摘要: #include <iostream>参考来自背包九讲之分组背包(注意三个循环的顺序,多重背包转换为01背包求解时,也有一定的顺序,否则则错)#include <cstdio>#include <string.h>#define INF -999999using namespace std;int max(int a,int b){ return a>b?a:b;}int main(){ int m,n,j,i,t,s[150][150],dp[10010]; while(scanf("%d%d",&n,&m),m, 阅读全文
posted @ 2013-04-29 14:54 一线添 阅读(159) 评论(0) 推荐(0) 编辑
摘要: #include <stdio.h>#include <string.h>int min(int a,int b,int c,int d){ int e=a<b?a:b; int f=c<d?c:d; int k=e<f?e:f; return k;}int main(){ int i1,i2,i3,i4; int f[6000],n; i1=i2=i3=i4=1; f[1]=1;//处理技巧 for (int i=2;i<=5842;++i) { f[i]=min(f[i1]*2,f[i2]*3,f[i3]*5,f[i4]*7... 阅读全文
posted @ 2013-04-25 14:59 一线添 阅读(103) 评论(0) 推荐(0) 编辑
摘要: #include <stdio.h>#include <string.h>int x[150][150][150];int w(int a,int b,int c){ if (a<=0||b<=0||c<=0) return 1; if (x[a][b][c]) return x[a][b][c];//用x[a][b][c]进行保留数据,为一个技巧 if (a>20||b>20||c>20) return x[a][b][c]=w(20,20,20); if (a<b&&b<c) return x[a][b 阅读全文
posted @ 2013-04-23 19:08 一线添 阅读(147) 评论(0) 推荐(0) 编辑