首页 / 算法 / 《算法竞赛入门经典》动态规划复习
《算法竞赛入门经典》动态规划复习
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了《算法竞赛入门经典》动态规划复习,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含6841字,纯文字阅读大概需要10分钟。
内容图文
![《算法竞赛入门经典》动态规划复习](/upload/InfoBanner/zyjiaocheng/1187/8365fae98bb14f63b36b3faae5496431.jpg)
codevs 4979 数塔
1 #define N 100 2 #include<iostream> 3usingnamespace std; 4 #include<cstdio> 5int a[N][N],b[N][N],n; 6int main() 7{ 8 scanf("%d",&n); 9for(int i=1;i<=n;++i) 10for(int j=1;j<=i;++j) 11 { 12 scanf("%d",&a[i][j]); 13 b[i][j]=a[i][j]; 14 } 15for(int i=n-1;i>=1;--i) 16for(int j=1;j<=i;++j) 17 { 18if(a[i+1][j]>=a[i+1][j+1]) 19 a[i][j]+=a[i+1][j]; 20else a[i][j]+=a[i+1][j+1]; 21 } 22int cont=1; 23 printf("%d\n",a[1][1]); 24 printf("%d-",b[1][1]); 25/*这个输出路径的方式很有意思,选择的路径根据a的性质,而且每次右移之后,就不可能再向左了,所以要cont++*/26for(int i=1;i<=n-1;++i) 27 { 28if(a[i+1][cont]>=a[i+1][cont+1]) 29 printf("%d",b[i+1][cont]); 30else{ 31 printf("%d",b[i+1][++cont]); 32 } 33if(i!=n-1) printf("-"); 34 } 35return0; 36 }
cogs
cogs 1243. 嵌套矩形
★★ 输入文件:qiantao.in
输出文件:qiantao.out
简单对比
时间限制:1 s 内存限制:128 MB
【题目描述】
有 n 个矩形,每个矩形可以用两个整数 a, b 描述,表示它的长和宽。矩形 X(a, b) 可以嵌套在矩形 Y(c, d) 中当且仅当 a<c, b<d,或者 b<c, a<d(相当于把矩形 X 旋转了 90°)。例如 (1, 5) 可以嵌套在 (6, 2) 内,但不能嵌套在 (3, 4) 内。
你的任务是选出尽量多的矩形,使得除了最后一个之外,每一个矩形都可以嵌套在下一个矩形内。
【输入格式】
第一行一个正整数 n (n <= 1000)。
接下来 n 行每行两个正整数 a, b 表示矩形 i 的长和宽。
【输出格式】
第一行一个整数 k 表示符合条件的最多矩形数。
第二行 k 个整数依次表示符合条件矩形的编号,要求字典序最小。
【样例输入】
8 14 9 15 19 18 12 9 10 19 17 15 9 2 13 13 10
【样例输出】
4 4 8 3 2
【样例说明】
最大嵌套深度为 4 。
4 个矩形分别是:4(9, 10) < 8(13, 10) < 3(18,12) < 2(15,19)
【来源】
算法竞赛入门经典 例题 9-2
1 #define N 1002 2 #include<iostream> 3usingnamespace std; 4 #include<cstdio> 5bool G[N][N]={0}; 6int n; 7struct Jx{ 8int a, b; 9}jx[N]; 10int d[N]={0}; 11void input() 12{ 13 scanf("%d",&n); 14for(int i=1;i<=n;++i) 15 scanf("%d%d",&jx[i].a,&jx[i].b); 16} 17void build_tu() 18{ 19for(int i=1;i<=n;++i) 20for(int j=1;j<i;++j) 21 { 22if(jx[i].a>jx[j].a&&jx[i].b>jx[j].b) 23 { 24 G[j][i]=true; 25 } 26if(jx[i].a>jx[j].b&&jx[i].b>jx[j].a) 27 { 28 G[j][i]=true; 29 } 30if(jx[i].a<jx[j].a&&jx[i].b<jx[j].b) 31 { 32 G[i][j]=true; 33 } 34if(jx[i].a<jx[j].b&&jx[i].b<jx[j].a) 35 { 36 G[i][j]=true; 37 } 38 } 39} 40int dp(int k) 41{ 42int &js=d[k]; 43if(js>0) return d[k]; 44 d[k]=1; 45for(int j=1;j<=n;++j) 46if(G[k][j]) 47 js=max(js,dp(j)+1); 48return js; 49} 50void prin(int k) 51{ 52 printf("%d ",k); 53for(int i=1;i<=n;++i) 54 { 55if(G[k][i]&&d[i]+1==d[k]) 56 { 57 prin(i); 58break; 59 } 60 } 61} 62int main() 63{ 64 freopen("qiantao.in","r",stdin); 65 freopen("qiantao.out","w",stdout); 66 input(); 67 build_tu(); 68int ans=0,k; 69for(int i=1;i<=n;++i) 70 { 71if(dp(i)>ans) 72 { 73 k=i; 74 ans=d[i]; 75 } 76 } 77 printf("%d\n",ans); 78 prin(k); 79 fclose(stdin); 80 fclose(stdout); 81return0; 82 }
描述
输入格式
第2行s
第3到n+2行为n种不同的面值
输出格式
第2行为最大值
测试样例1
输入
3
6
1
2
3
输出
2
6
备注
1<=s<=10000
1<=a[i]<=s
1 /* 背包问题的变式 */ 2 #include<iostream> 3usingnamespace std; 4 #include<cstdio> 5 #include<cstring> 6#define N 105 7#define S 10010 8int n,s,a[N]; 9int minv[S],maxv[S]; 10int main() 11{ 12 scanf("%d%d",&n,&s); 13for(int i=1;i<=n;++i) 14 scanf("%d",&a[i]); 15 memset(minv,99,sizeof(minv)); 16 memset(maxv,-99,sizeof(maxv)); 17 minv[0]=maxv[0]=0; 18for(int i=1;i<=s;++i) 19for(int j=1;j<=n;++j) 20if(i>=a[j]) 21 { 22 minv[i]=min(minv[i],minv[i-a[j]]+1); 23 maxv[i]=max(maxv[i],maxv[i-a[j]]+1); 24 } 25 printf("%d\n%d",minv[s],maxv[s]); 26return0; 27 }
UVA - 437 The Tower of Babylon
1 #define N 100 2 #include<cstring> 3 #include<iostream> 4usingnamespace std; 5 #include<cstdio> 6bool G[N][N]; 7int d[N],n,t=0; 8struct Lf{ 9int x,y,z; 10}lf[N]; 11void input() 12{ 13 memset(G,false,sizeof(G)); 14 memset(d,0,sizeof(d)); 15int x,y,z; 16 t=0; 17for(int i=1;i<=n;++i) 18 { 19 scanf("%d%d%d",&x,&y,&z); 20 ++t; 21 lf[t].x=x;lf[t].y=y;lf[t].z=z; 22 ++t; 23 lf[t].x=x;lf[t].y=z;lf[t].z=y; 24 ++t; 25 lf[t].x=y;lf[t].y=z;lf[t].z=x; 26 } 2728} 29void build_tu() 30{ 31for(int i=1;i<=t;++i) 32for(int j=1;j<i;++j) 33 { 34if(lf[i].x<lf[j].x&&lf[i].y<lf[j].y) 35 G[i][j]=true; 36if(lf[i].x<lf[j].y&&lf[i].y<lf[j].x) 37 G[i][j]=true; 38if(lf[j].x<lf[i].x&&lf[j].y<lf[i].y) 39 G[j][i]=true; 40if(lf[j].x<lf[i].y&&lf[j].y<lf[i].x) 41 G[j][i]=true; 42 } 43} 44int dp(int k) 45{ 46if(d[k]>0) return d[k]; 47 d[k]=lf[k].z; 48for(int i=1;i<=t;++i) 49if(G[k][i]) d[k]=max(d[k],dp(i)+lf[k].z); 50return d[k]; 51} 52int main() 53{ 54int kase=0; 55while(scanf("%d",&n)==1&&n) 56 { 57 ++kase; 58 input(); 59 build_tu(); 60int ans=0; 61for(int i=1;i<=t;++i) 62 { 63 ans=max(ans,dp(i)); 64 } 65 printf("Case %d: maximum height = %d\n",kase,ans); 66 } 67return0; 68 }
1 #include<cstring> 2#define N 1008 3 #include<cmath> 4 #include<iostream> 5usingnamespace std; 6 #include<cstdio> 7int n; 8struct Zb{ 9double x,y; 10}zb[N]; 11double d[N][N]={0}; 12double dist(int a,int b) 13{ 14return sqrt((zb[a].x-zb[b].x)*(zb[a].x-zb[b].x)+(zb[a].y-zb[b].y)*(zb[a].y-zb[b].y)); 15} 16void input() 17{ 18for(int i=1;i<=n;++i) 19 scanf("%lf%lf",&zb[i].x,&zb[i].y); 20} 21double dp(int i,int j)/*一开始误打成int,结果错了*/22{ 23if(d[i][j]>0) 24return d[i][j]; 25if(i==n-1) 26 d[i][j]=dist(n-1,n)+dist(j,n); 27else28 d[i][j]=min(dp(i+1,j)+dist(i,i+1),dp(i+1,i)+dist(i+1,j)); 29return d[i][j]; 30} 31int main() 32{ 33while(scanf("%d",&n)==1) 34 { 35 input(); 36 memset(d,0,sizeof(d)); 37 dp(2,1); 38 printf("%0.2lf\n",d[2][1]+dist(1,2)); 39 } 40return0; 41 }
1 /* 一开始忘记把nex数组重置,后来发现输出少了一个‘\n’ */ 2 #include<iostream> 3usingnamespace std; 4 #include<cstdio> 5#define N 55 6#define T 10000 7 #include<cstring> 8int songg[N],f[T],kase,n,t,nex[T]; 9int main() 10{ 11 scanf("%d",&kase); 12int opt=0; 13while(kase--) 14 { 15 opt++; 16 memset(songg,0,sizeof(songg)); 17 memset(nex,0,sizeof(nex)); 18 memset(f,0,sizeof(f)); 19 scanf("%d%d",&n,&t); 20for(int i=1;i<=n;++i) 21 scanf("%d",&songg[i]); 22for(int i=1;i<=n;++i) 23 { 24for(int j=t-1;j>=songg[i];--j) 25 { 26if(f[j]<f[j-songg[i]]+1||(f[j]==f[j-songg[i]]+1&&nex[j]<nex[j-songg[i]]+songg[i])) 27 { 28 nex[j]=nex[j-songg[i]]+songg[i]; 29 f[j]=f[j-songg[i]]+1; 30 } 31 } 3233 } 34/*注意题目要求的歌曲数目对优先,在这个基础上,然后时间尽量长,那么Dp转移的时候就要把两个条件都考虑到*/35/*int maxtim=0,maxnum=0; 36 for(int i=1;i<=t-1;++i) 37 { 38 if(f[i]+1>maxnum||(f[i]+1==maxnum&&maxtim<nex[i]+678)) 39 { 40 maxnum=f[i]+1; 41 maxtim=nex[i]+678; 42 } 43 }*/44 printf("Case %d: %d %d\n",opt,f[t-1]+1,nex[t-1]+678); 45// printf("Case %d: %d %d",opt,maxnum,maxtim); 46// if(kase)printf("\n");47 } 48return0; 49 }
原文:http://www.cnblogs.com/c1299401227/p/5978569.html
内容总结
以上是互联网集市为您收集整理的《算法竞赛入门经典》动态规划复习全部内容,希望文章能够帮你解决《算法竞赛入门经典》动态规划复习所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。