随笔分类 -  动态规划

ACM重点
摘要:http://blog.csdn.net/abcjennifer/article/details/5805330n堆石子排成一条直线找不到题目,就copy了别人的代码,自己写的无法验证对错View Code #include <iostream> using namespace std;#define M 101#define INF 1000000000int n,f[M][M],sum[M][M],stone[M];int main(){ int i,j,k,t; cin>>n; for(i=1;i<=n;i++) scanf("%d",& 阅读全文
posted @ 2011-12-15 20:46 Because Of You 阅读(3745) 评论(0) 推荐(1)
摘要:链接http://www.rqnoj.cn/Problem_6.html题目描述题目描述 金明今天很开心,家里购置的新房就要领钥匙了,新房里有一间金明自己专用的很宽敞的房间。更让他高兴的是,妈妈昨天对他说:“你的房间需要购买哪些物品,怎么布置,你说了算,只要不超过N元钱就行”。今天一早,金明就开始做预算了,他把想买的物品分为两类:主件与附件,附件是从属于某个主件的,下表就是一些主件与附件的例子:主件 附件电脑 打印机,扫描仪书柜 图书书桌 台灯,文具工作椅 无 如果要买归类为附件的物品,必须先买该附件所属的主件。每个主件可以有0个、1个或2个附件。附件不再有从属于自己的附件。金明想买的东西.. 阅读全文
posted @ 2011-12-13 12:39 Because Of You 阅读(456) 评论(0) 推荐(0)
摘要:依赖关系形成一棵树,要选子节点必先选择其父节点关键:把背包放在树上来做,也就是树上的01背包View Code #include<stdio.h>#include<string.h>#include<vector>using namespace std;struct node{ int v,next;}edge[10010];int head[110];int dp[110][110];int n,m,tot;void add(int s,int t){ edge[tot].v=t; edge[tot].next=head[s]; head[s]=tot++ 阅读全文
posted @ 2011-12-12 20:42 Because Of You 阅读(530) 评论(0) 推荐(0)
摘要:关键点:对每个箱子的dimension 排个序,这样才能判断某个箱子是否真的能放入另一个箱子内建好图后求一个图中的最长路即可View Code #include<stdio.h>#include<string.h>#include<algorithm>using namespace std;const int inf = 100000000;int box[510][1010];int map[510][510];int n,d;bool ok;int count=0;bool solve(int a,int b){ int i,j; bool flag=t 阅读全文
posted @ 2011-12-06 22:01 Because Of You 阅读(407) 评论(0) 推荐(0)
摘要:第一道记录路径的题目Charlie's ChangeTime Limit: 1000MSMemory Limit: 30000KTotal Submissions: 1998Accepted: 476DescriptionCharlie is a driver of Advanced Cargo Movement, Ltd. Charlie drives a lot and so he often buys coffee at coffee vending machines at motorests. Charlie hates change. That is basically th 阅读全文
posted @ 2011-11-27 11:32 Because Of You 阅读(730) 评论(0) 推荐(0)
摘要:此类背包典型的关系是若想选b,你必须先选a,从而产生了一层依赖关系,然后给你一定限量的总钱数,让你买最大价值的东西就让我们从hdu 3449 来搞定这类最简单的依赖背包吧有很多个箱子,想买箱子中的物品必须先买下箱子,典型的依赖背包dp[i][j]代表前i个箱子花费j的钱能获得的最大价值,则可以想到每次在对一个箱子进行dp更新状态时都应该利用前面的结果来更新以前做那道金明的预算方案时,就是没有利用上层的结果来更新才一直错,dp的本质都被我给忽略了,囧!View Code #include<cstdio>#include<cstring>int dp[60][100010] 阅读全文
posted @ 2011-11-26 14:11 Because Of You 阅读(1784) 评论(0) 推荐(0)
摘要:蛮简单的dp,只是要注意会超intdp[i][j]代表i个数以j结尾的数列个数#include<stdio.h>#include<string.h>__int64 dp[11][2001];int i,j,k;void init(){ memset(dp,0,sizeof(dp)); for(i=1;i<=2000;i++) dp[1][i]=1; for(i=2;i<=10;i++) { for(j=i;j<=2000;j++) { for(k=1;k<=j/2;k++) { dp[i][j]+=dp[i-1][k]; } } }}int ma 阅读全文
posted @ 2011-11-24 10:36 Because Of You 阅读(336) 评论(0) 推荐(0)
摘要:简单的方法来自http://poj.org/showmessage?message_id=156697#include<stdio.h>#include<string.h>int dp[100010];int num[110],v[110];int used[100010];int main(){ int n,m,i,j; while(scanf("%d%d",&n,&m),(n||m)){ for(i=0;i<n;i++) scanf("%d",&v[i]); for(i=0;i<n;i++) 阅读全文
posted @ 2011-11-21 03:18 Because Of You 阅读(326) 评论(0) 推荐(0)
摘要:The Fewest CoinsTime Limit:2000MSMemory Limit:65536KTotal Submissions:2618Accepted:770DescriptionFarmer John has gone to town to buy some farm supplies. Being a very efficient man, he always pays for his goods in such a way that the smallest number of coins changes hands, i.e., the number of coins h 阅读全文
posted @ 2011-11-21 02:53 Because Of You 阅读(331) 评论(0) 推荐(0)
摘要:O(nlogn)的算法关键是它建立了一个数组temp[],temp[i]表示长度为i的不下降序列中结尾元素的最小值,用top表示数组目前的长度,算法完成后top的值即为最长不下降子序列的长度。 设当前的以求出的长度为top,则判断num[i]和temp[top]: 1.如果num[i]>=temp[top],即num[i]大于长度为top的序列中的最后一个元素,这样就可以使序列的长度增加1,即top++,然后现在的temp[top]=num[i]; 2.如果num[i]<temp[top],那么就在temp[1]...temp[top]中找到最大的j,使得temp[j]<nu 阅读全文
posted @ 2011-11-20 22:25 Because Of You 阅读(3657) 评论(0) 推荐(1)
摘要:返回的是RMQ的下标,有个地方要注意,就是在rmq模板比较大小的地方要改成<=,要不然如果有一连串的相同数字的话本来是要取的,结果没取#include<string.h>#include<stdio.h>#include<math.h>const int M=1010;int min(int a,int b){return a<b?a:b;}int dp[20][M],LOG[M];void Make_Rmqindex(int n,char b[]){ int i,j; for(i=1;i<=n;i++) dp[0][i]=i; for(i 阅读全文
posted @ 2011-11-20 12:02 Because Of You 阅读(770) 评论(2) 推荐(0)
摘要:每年做一次完全背包,累加结果#include<stdio.h>#include<string.h>int dp[1000000],w[11],v[11];int sum,n,y;int max(int a,int b){return a>b?a:b;}void DP(){ int i,j,V=sum/1000; for(i=0;i<=V;i++) dp[i]=0; for(i=0;i<n;i++) for(j=w[i];j<=V;j++) dp[j]=max(dp[j],dp[j-w[i]]+v[i]); sum+=dp[V];}int main 阅读全文
posted @ 2011-11-19 20:26 Because Of You 阅读(278) 评论(0) 推荐(0)
摘要:看了别人的,就不讲了#include<stdio.h>#include<string.h>int dp[10000];int a[6];int min(int a,int b){ if(a==-1)return b; return a<b?a:b;}int main(){ int T; while(scanf("%d",&T)!=EOF) { while(T--){ int i,j; int upper = 0; for(i=0;i<6;i++) scanf("%d",&a[i]); upper= 10 阅读全文
posted @ 2011-11-19 17:11 Because Of You 阅读(264) 评论(0) 推荐(0)
摘要:完全背包,注意初始化的细节dp【0】=0;这道题要求的是恰好装满背包的最小的价值,所以初始状态下,只有dp[0]满足条件,即容量为0的背包可能被价值为0的东西(即木有东西)装满背包,其他容量的背包均没有合法解,都是无穷大,之所以是恰好装满是因为贮蓄罐的增重是一定的#include<stdio.h>#include<string.h>int dp[10000];int w[505],v[505];int min(int a,int b){return a<b?a:b;}int main(){ int t,e,f,i,j,k,n; scanf("%d&quo 阅读全文
posted @ 2011-11-19 15:53 Because Of You 阅读(854) 评论(1) 推荐(0)
摘要:判断能不能将总的物品分两半,中间拆分的时候有点多重背包的思想#include<iostream>#include<string>#include<algorithm>using namespace std;int value[1005];int dp[60005];int num[7];int main(){ int i,j,d,ans,sum,ncase=1; while(scanf("%d%d%d%d%d%d",&num[1],&num[2],&num[3],&num[4],&num[5],&a 阅读全文
posted @ 2011-11-19 15:11 Because Of You 阅读(231) 评论(0) 推荐(0)
摘要:三种背包,每组至少、至多取一个或随意取多少注释在代码中#include<cstdio>#include<cstring>int dp[110][110];int max(int a,int b){ return a>b?a:b;}int main(){ int n,T,i,j,k,m,s,w,v; while(scanf("%d%d",&n,&T)!=EOF) { memset(dp,0,sizeof(dp)); for(i=1;i<=n;i++) { scanf("%d%d",&m,& 阅读全文
posted @ 2011-11-19 15:00 Because Of You 阅读(999) 评论(3) 推荐(0)
摘要:有N件物品和一个容量为V的背包。第i件物品的费用是c[i],价值是w[i]。这些物品被划分为若干组,每组中的物品互相冲突,最多选一件。求解将哪些物品装入背包可使这些物品的费用总和不超过背包容量,且价值总和最大。算法这个问题变成了每组物品有若干种策略:是选择本组的某一件,还是一件都不选。也就是说设f[k][v]表示前k组物品花费费用v能取得的最大权值,则有:f[k][v]=max{f[k-1][v],f[k-1][v-c[i]]+w[i]|物品i属于第k组}使用一维数组的伪代码如下:for所有的组kfor v=V..0for所有的i属于组kf[v]=max{f[v],f[v-c[i]]+w[i] 阅读全文
posted @ 2011-11-19 02:09 Because Of You 阅读(456) 评论(0) 推荐(0)
摘要:挺简单的DP,可是没有注意到数据会超范围,上官网搜了数据才知道,后来改成了__int64,发现还是不行,改成double,AC了带血的AC。。。#include<stdio.h>#include<string.h>double dp[110][15];int main(){ int k,n; int i,j; while(scanf("%d%d",&k,&n)!=EOF) { memset(dp,0,sizeof(dp)); for(i=1;i<=k+1;i++) dp[1][i]=1; for(i=2;i<=n;i++) 阅读全文
posted @ 2011-11-18 20:14 Because Of You 阅读(245) 评论(0) 推荐(0)
摘要:枚举的时候体积和组中的物品顺序换了,果断WA深刻理解了,但又感觉不怎么会表达,囧#include<stdio.h>#include<string.h>int a[110][110];int dp[110];int max(int a,int b){ return a>b?a:b;}int main(){ int i,j,m,n; while(scanf("%d%d",&n,&m),(n||m)) { for(i=1;i<=n;i++) for(j=1;j<=m;j++) scanf("%d",&a 阅读全文
posted @ 2011-11-17 21:00 Because Of You 阅读(296) 评论(0) 推荐(0)
摘要:View Code //要注意dp转移的时候两重循环的顺序,w[x](鞋子的价格) 可能为0,如果换一下顺序可能会导致某双鞋被选了两次#include<stdio.h>#include<string.h>int dp[11][10010];int belong[10010];int w[10010],v[10010];int flag[20];int max(int a,int b){ return a>b?a:b;}int main(){ int n,m,k,i,j; while(scanf("%d%d%d",&n,&m,&a 阅读全文
posted @ 2011-11-17 19:57 Because Of You 阅读(541) 评论(2) 推荐(0)