• 《算法竞赛入门经典》动态规划复习


    codevs 4979 数塔

     1 #define N 100
     2 #include<iostream>
     3 using namespace std;
     4 #include<cstdio>
     5 int a[N][N],b[N][N],n;
     6 int main()
     7 {
     8     scanf("%d",&n);
     9     for(int i=1;i<=n;++i)
    10       for(int j=1;j<=i;++j)
    11       {
    12           scanf("%d",&a[i][j]);
    13           b[i][j]=a[i][j];
    14       }
    15     for(int i=n-1;i>=1;--i)
    16       for(int j=1;j<=i;++j)
    17       {
    18           if(a[i+1][j]>=a[i+1][j+1])
    19             a[i][j]+=a[i+1][j];
    20           else a[i][j]+=a[i+1][j+1];
    21       }
    22     int cont=1;
    23     printf("%d
    ",a[1][1]);
    24     printf("%d-",b[1][1]);
    25 /*这个输出路径的方式很有意思,选择的路径根据a的性质,而且每次右移之后,就不可能再向左了,所以要cont++*/
    26     for(int i=1;i<=n-1;++i)
    27     {
    28         if(a[i+1][cont]>=a[i+1][cont+1])
    29           printf("%d",b[i+1][cont]);
    30         else{
    31             printf("%d",b[i+1][++cont]);
    32         }
    33         if(i!=n-1) printf("-");
    34     }
    35     return 0;
    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>
     3 using namespace std;
     4 #include<cstdio>
     5 bool G[N][N]={0};
     6 int n;
     7 struct Jx{
     8     int a, b;
     9 }jx[N];
    10 int d[N]={0};
    11 void input()
    12 {
    13     scanf("%d",&n);
    14     for(int i=1;i<=n;++i)
    15       scanf("%d%d",&jx[i].a,&jx[i].b);
    16 }
    17 void build_tu()
    18 {
    19     for(int i=1;i<=n;++i)
    20       for(int j=1;j<i;++j)
    21       {
    22           if(jx[i].a>jx[j].a&&jx[i].b>jx[j].b)
    23           {
    24               G[j][i]=true;
    25           }
    26         if(jx[i].a>jx[j].b&&jx[i].b>jx[j].a)
    27           {
    28               G[j][i]=true;
    29           }
    30         if(jx[i].a<jx[j].a&&jx[i].b<jx[j].b)
    31           {
    32               G[i][j]=true;
    33           }
    34         if(jx[i].a<jx[j].b&&jx[i].b<jx[j].a)
    35           {
    36               G[i][j]=true;
    37           }
    38       }
    39 }
    40 int dp(int k)
    41 {
    42     int &js=d[k];
    43     if(js>0) return d[k];
    44     d[k]=1;
    45     for(int j=1;j<=n;++j)
    46       if(G[k][j])
    47       js=max(js,dp(j)+1);
    48     return js;
    49 }
    50 void prin(int k)
    51 {
    52     printf("%d ",k);
    53     for(int i=1;i<=n;++i)
    54     {
    55         if(G[k][i]&&d[i]+1==d[k])
    56         {
    57             prin(i);
    58             break;
    59         }
    60     }
    61 }
    62 int main()
    63 {
    64     freopen("qiantao.in","r",stdin);
    65     freopen("qiantao.out","w",stdout);
    66     input();
    67     build_tu();
    68     int ans=0,k;
    69     for(int i=1;i<=n;++i)
    70     {
    71         if(dp(i)>ans)
    72         {
    73             k=i;
    74             ans=d[i];
    75         }
    76     }
    77     printf("%d
    ",ans);
    78     prin(k);
    79     fclose(stdin);
    80     fclose(stdout);
    81     return 0;
    82 }
    TYVJ P1214 硬币问题
    时间: 1000ms / 空间: 131072KiB / Java类名: Main

    描述

      有n种硬币,面值为别为a[1],a[2],a[3]……a[n],每种都有无限多。给定非负整数s,可以选取多少个硬币使得面值和恰好为s?输出硬币数目最小值和最大值

    输入格式

    第1行n
    第2行s
    第3到n+2行为n种不同的面值

    输出格式

    第1行为最小值
    第2行为最大值

    测试样例1

    输入





    3

    输出


    6

    备注

    1<=n<=100
    1<=s<=10000
    1<=a[i]<=s
     1 /*背包问题的变式*/
     2 #include<iostream>
     3 using namespace std;
     4 #include<cstdio>
     5 #include<cstring>
     6 #define N 105
     7 #define S 10010
     8 int n,s,a[N];
     9 int minv[S],maxv[S];
    10 int main()
    11 {
    12     scanf("%d%d",&n,&s);
    13     for(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;
    18     for(int i=1;i<=s;++i)
    19       for(int j=1;j<=n;++j)
    20       if(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
    %d",minv[s],maxv[s]);
    26     return 0;
    27 }

     UVA - 437 The Tower of Babylon

     1 #define N 100
     2 #include<cstring>
     3 #include<iostream>
     4 using namespace std;
     5 #include<cstdio>
     6 bool G[N][N];
     7 int d[N],n,t=0;
     8 struct Lf{
     9     int x,y,z;
    10 }lf[N];
    11 void input()
    12 {
    13     memset(G,false,sizeof(G));
    14     memset(d,0,sizeof(d));
    15     int x,y,z;
    16     t=0;
    17     for(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     }
    27   
    28 }
    29 void build_tu()
    30 {
    31     for(int i=1;i<=t;++i)
    32       for(int j=1;j<i;++j)
    33       {
    34           if(lf[i].x<lf[j].x&&lf[i].y<lf[j].y)
    35             G[i][j]=true;
    36           if(lf[i].x<lf[j].y&&lf[i].y<lf[j].x)
    37             G[i][j]=true;
    38           if(lf[j].x<lf[i].x&&lf[j].y<lf[i].y)
    39             G[j][i]=true;
    40           if(lf[j].x<lf[i].y&&lf[j].y<lf[i].x)
    41             G[j][i]=true;
    42       }
    43 }
    44 int dp(int k)
    45 {
    46     if(d[k]>0) return d[k];
    47     d[k]=lf[k].z;
    48     for(int i=1;i<=t;++i)
    49       if(G[k][i])  d[k]=max(d[k],dp(i)+lf[k].z);
    50     return d[k];
    51 }
    52 int main()
    53 {
    54     int kase=0;
    55     while(scanf("%d",&n)==1&&n)
    56     {
    57         ++kase;
    58         input();
    59         build_tu();
    60         int ans=0;
    61         for(int i=1;i<=t;++i)
    62         {
    63             ans=max(ans,dp(i));
    64         }
    65         printf("Case %d: maximum height = %d
    ",kase,ans);
    66     }
    67     return 0;
    68 }

     UVA - 1347 Tour


    1
    #include<cstring> 2 #define N 1008 3 #include<cmath> 4 #include<iostream> 5 using namespace std; 6 #include<cstdio> 7 int n; 8 struct Zb{ 9 double x,y; 10 }zb[N]; 11 double d[N][N]={0}; 12 double dist(int a,int b) 13 { 14 return 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 } 16 void input() 17 { 18 for(int i=1;i<=n;++i) 19 scanf("%lf%lf",&zb[i].x,&zb[i].y); 20 } 21 double dp(int i,int j)/*一开始误打成int,结果错了*/ 22 { 23 if(d[i][j]>0) 24 return d[i][j]; 25 if(i==n-1) 26 d[i][j]=dist(n-1,n)+dist(j,n); 27 else 28 d[i][j]=min(dp(i+1,j)+dist(i,i+1),dp(i+1,i)+dist(i+1,j)); 29 return d[i][j]; 30 } 31 int main() 32 { 33 while(scanf("%d",&n)==1) 34 { 35 input(); 36 memset(d,0,sizeof(d)); 37 dp(2,1); 38 printf("%0.2lf ",d[2][1]+dist(1,2)); 39 } 40 return 0; 41 }
     1 /*一开始忘记把nex数组重置,后来发现输出少了一个‘
    ’*/
     2 #include<iostream>
     3 using namespace std;
     4 #include<cstdio>
     5 #define N 55
     6 #define T 10000
     7 #include<cstring>
     8 int songg[N],f[T],kase,n,t,nex[T];
     9 int main()
    10 {
    11     scanf("%d",&kase);
    12     int opt=0;
    13     while(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);
    20         for(int i=1;i<=n;++i)
    21           scanf("%d",&songg[i]);
    22         for(int i=1;i<=n;++i)
    23         {
    24           for(int j=t-1;j>=songg[i];--j)
    25            {
    26               if(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             }
    32              
    33         }
    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
    ",opt,f[t-1]+1,nex[t-1]+678);
    45     //    printf("Case %d: %d %d",opt,maxnum,maxtim);        
    46     //    if(kase)printf("
    ");
    47     }
    48     return 0;
    49 }
                     
  • 相关阅读:
    redis深度理解底层锁原理
    深度完整的了解MySQL锁
    今天的文章很不一般
    利用h5来进行定位当前位置
    workerman(环境+初识)
    Nginx(防止压力测试的恶意攻击)
    Java Web框架——自己动手实现一个简化版的Spring IOC框架
    设计模式——策略模式
    数据库——深入理解MySQL事务
    缓存——Redis和Memcache的对比
  • 原文地址:https://www.cnblogs.com/c1299401227/p/5978569.html
Copyright © 2020-2023  润新知