• codevs 数字三角形集结


    添在前面的一句话:初学DP,若有错误,请指出,不能误人子弟,欢迎大家提出意见.水平不高,博客写的比较粗糙,代码也挺丑,请见谅.

    最原始的数字三角形:

    1220 数字三角形

     

     时间限制: 1 s
     空间限制: 128000 KB
     题目等级 : 黄金 Gold
     
     
     
    题目描述 Description

    如图所示的数字三角形,从顶部出发,在每一结点可以选择向左走或得向右走,一直走到底层,要求找出一条路径,使路径上的值最大。

    输入描述 Input Description

    第一行是数塔层数N(1<=N<=100)。

    第二行起,按数塔图形,有一个或多个的整数,表示该层节点的值,共有N行。

    输出描述 Output Description

    输出最大值。

    样例输入 Sample Input

    5

    13

    11 8

    12 7 26

    6 14 15 8

    12 7 13 24 11

    样例输出 Sample Output

    86

    数据范围及提示 Data Size & Hint
     

    思路:因为f[i][j] 从 f[i + 1][j] 或者 f[i + 1][j + 1] 转移过来,但是我们要的是最大路径长度,所以从max(f[i +1][j],f[i + 1][j + 1])是最优解,所以DP转移方程为f[i][j]  += max(f[i + 1][j],f[i + 1][j + 1]);

    代码:

     1 #include <iostream>
     2 #include <cstdio>
     3 #define X 1007
     4 
     5 int f[X][X];
     6 
     7 int max(int x,int y){
     8     return x > y ? x : y; 
     9 }
    10 
    11 inline int read(){
    12     int x = 0,f = 1;char c = getchar();
    13     while(c < '0' || c > '9'){if(c == '-')f = -1;c = getchar();}
    14     while(c >= '0' && c <= '9'){x = x * 10 + c - '0';c = getchar();}
    15     return x * f;
    16 }
    17 
    18 int main(){
    19     int n;
    20     n = read();
    21     for(int i = 1;i <= n;++ i)
    22         for(int j = 1;j <= i;++ j)
    23             f[i][j] = read();
    24     for(int i = n - 1;i >= 1;-- i)
    25         for(int j = 1;j <= i;++ j)
    26             f[i][j] += max(f[i + 1][j],f[i + 1][j + 1]);
    27     printf("%d",f[1][1]);
    28 }    
    View Code

     数字三角形w

    2189 数字三角形W

     

     时间限制: 1 s
     空间限制: 32000 KB
     题目等级 : 黄金 Gold
     
     
    题目描述 Description

    数字三角形
    要求走到最后mod 100最大

    输入描述 Input Description

    第1行n,表示n行
    第2到n+1行为每个的权值

    输出描述 Output Description

    mod 100最大值

    样例输入 Sample Input

    2
    1
    99 98

    样例输出 Sample Output

    99

    数据范围及提示 Data Size & Hint

    n<=25

    思路:根据mod 100这个条件,按照上一个题,已经不满足与最优子结构,所以我们要加一维。

    可达性DP,我们开一个bool数组 f[i][j][k],f[i][j][k]表示i行,j列,从下面到k值能不能走通,所以我们就想出DP转移方程了,f[i][j][k] = f[i + 1][j][v] | f[i + 1][j + 1][v];(v = (k + 100 - a[i][j] %100) % 100)(ps:这个地方挺重要的,如果k数值 < a[i][j]的话,就会成为负数,然而他是比a[i][j]要大的,所以我们加上一个100也没有关系,建议这个地方好好领悟.先让a[i][j] % 100可以有效的防a[i][j] > k + 100

    代码:

     1 #include <iostream>
     2 #include <cstdio>
     3 #define X 30
     4 
     5 int a[X][X];
     6 bool f[X][X][101];//f[i][j][k] i 表示 第i行 j表示第j列  k表示上面的路径%100到k这个值 bool型数组,能到k值为1,到不了为0 
     7 
     8 int max(int x,int y){
     9     return x > y ? x : y;
    10 }//max函数,我没用using namespace std  
    11 
    12 inline int read(){
    13     int x = 0,f = 1;char c = getchar();
    14     while(c < '0' || c > '9'){if(c == '-')f = -1;c = getchar();}
    15     while(c >= '0' && c <= '9'){x = x * 10 + c - '0';c = getchar();}
    16     return x * f;
    17 }//快读 不解释 
    18 
    19 int main(){
    20     int n,ans = 0;//n 如题 有n层的数字三角形 
    21     n = read();
    22     for(int i = 1;i <= n;++ i)
    23         for(int j = 1;j <= i;++ j)
    24             a[i][j] = read();//读入三角形 
    25     for(int i = 1;i <= n;++ i)f[n][i][((a[n][i] % 100) + 100) % 100] = true;//在最下面一层,不会有人转移到他
    26                                                                             //所以这是初始条件,a[n][i] % 100 这个值会到达,所以标记为true 
    27     for(int i = n - 1;i >= 1;-- i){
    28         for(int j = 1;j <= i;++ j){
    29             for(int k = 0;k <= 99;++ k){
    30                 int v = (k - (a[i][j] %100) + 100) % 100;
    31                 f[i][j][k] = f[i + 1][j][v] | f[i + 1][j + 1][v];
    32             }
    33         }
    34     }//核心代码,根据条件很容易得到DP转移方程 f[i][j][k] = f[i + 1][j] [(k - a[i][j]) % 100] | f[i + 1][j + 1][(k - a[i][j]) % 100]; 
    35     for(int i = 99;i >= 0;-- i)
    36         if(f[1][1][i]){ans = i;break;}//从后往前推,如果这个到达了这个i值,直接break就好.    
    37     printf("%d",ans);
    38 }
    View Code

    数字三角形ww

    2193 数字三角形WW

     

     时间限制: 1 s
     空间限制: 32000 KB
     题目等级 : 钻石 Diamond
     
     
     
    题目描述 Description

    数字三角形必须经过某一个点,使之走的路程和最大

    输入描述 Input Description

    第1行n,表示n行
    第2到n+1行为每个的权值
    程序必须经过n div 2,n div 2这个点

    输出描述 Output Description

    最大值

    样例输入 Sample Input
    #include <iostream>
    #include <cstdio>
    #define X 30
    
    int f[X][X];
    
    inline int read(){
        int x = 0,f = 1;char c = getchar();
        while(c < '0' || c > '9'){if(c == '-')f = -1;c = getchar();}
        while(c >= '0' && c <= '9'){x = x * 10 + c - '0';c = getchar();}
        return x * f;
    }
    
    int max(int x,int y){
        return x > y ? x : y;
    }
    
    int main(){
        int n = read(),x;
        for(int i = 1;i <= n;++ i)
            for(int j = 1;j <= i;++ j)
                f[i][j] = read();
        for(int i = 1;i < n / 2;++ i)f[n/2][i] = -0x3f3f3f3f;
        for(int i = n - 1;i >= 1;-- i){
            for(int j = 1;j <= i;++ j){
                f[i][j] += max(f[i + 1][j],f[i + 1][j + 1]);
            }
        }
        printf("%d",f[1][1]);
    }
    View Code

    2
    1
    1 1

    样例输出 Sample Output

    2

    数据范围及提示 Data Size & Hint

    n <=25

    思路:只能走f[n / 2][n / 2]这条路,我们就好在n / 2这一行的除了f[n / 2][n / 2]全部设成最小值就可以了.

    代码:

     1 #include <iostream>
     2 #include <cstdio>
     3 #define X 30
     4 
     5 int f[X][X];
     6 
     7 inline int read(){
     8     int x = 0,f = 1;char c = getchar();
     9     while(c < '0' || c > '9'){if(c == '-')f = -1;c = getchar();}
    10     while(c >= '0' && c <= '9'){x = x * 10 + c - '0';c = getchar();}
    11     return x * f;
    12 }
    13 
    14 int max(int x,int y){
    15     return x > y ? x : y;
    16 }
    17 
    18 int main(){
    19     int n = read(),x;
    20     for(int i = 1;i <= n;++ i)
    21         for(int j = 1;j <= i;++ j)
    22             f[i][j] = read();
    23     for(int i = 1;i < n / 2;++ i)f[n/2][i] = -0x3f3f3f3f;
    24     for(int i = n - 1;i >= 1;-- i){
    25         for(int j = 1;j <= i;++ j){
    26             f[i][j] += max(f[i + 1][j],f[i + 1][j + 1]);
    27         }
    28     }
    29     printf("%d",f[1][1]);
    30 }
    View Code

    数字三角形WWW:

    2198 数字三角形WWW

     

     时间限制: 1 s
     空间限制: 32000 KB
     题目等级 : 钻石 Diamond
     
     
     
    题目描述 Description

    数字三角形必须经过某一个点,使之走的路程和最大

    输入描述 Input Description

    第1行n,表示n行 
    第2到n+1行为每个的权值
    第n+2行为两个数x,y表示必须经过的点

    输出描述 Output Description

    最大值

    样例输入 Sample Input

    2
    1
    1 1
    1 1

    样例输出 Sample Output

    2

    数据范围及提示 Data Size & Hint

    n<=25

    思路:同上一题差不多,就是将n / 2那一行改成x,然后特判一下y位置就好了,不多说,上代码.

    代码:

     1 #include <iostream>
     2 #include <cstdio>
     3 #define X 30
     4 
     5 int f[X][X];
     6 
     7 inline int read(){
     8     int x = 0,f = 1;char c = getchar();
     9     while(c < '0' || c > '9'){if(c == '-')f = -1;c = getchar();}
    10     while(c >= '0' && c <= '9'){x = x * 10 + c - '0';c = getchar();}
    11     return x * f;
    12 }
    13 
    14 int max(int x,int y){
    15     return x > y ? x : y;
    16 }
    17 
    18 int main(){
    19     int n = read(),x,y,tmp;
    20     for(int i = 1;i <= n;++ i)
    21         for(int j = 1;j <= i;++ j)
    22             f[i][j] = read();
    23     x = read(),y = read();
    24     tmp = f[x][y];
    25     for(int i = 1;i <= x;++ i)f[x][i] = -0x3f3f3f3f;
    26     f[x][y] = tmp;
    27     for(int i = n - 1;i >= 1;-- i){
    28         for(int j = 1;j <= i;++ j){
    29             f[i][j] += max(f[i + 1][j],f[i + 1][j + 1]);
    30         }
    31     }
    32     printf("%d",f[1][1]);
    33 }
    View Code
  • 相关阅读:
    使用Xcode和Instruments调试解决iOS内存泄露(转载) sansan
    GCD介绍(二): 多核心的性能(转载) sansan
    iphone 常用的<app>info.plist设置(转载) sansan
    GCD介绍(一): 基本概念和Dispatch Queue (转载) sansan
    iOS 证书与签名 解惑详解[转] sansan
    Xcode快捷键 sansan
    GCD介绍(三): Dispatch Sources(转载) sansan
    Apple开发者授权 sansan
    MFC中Spin control的使用
    c++ windows mobile中设置菜单活动与否
  • 原文地址:https://www.cnblogs.com/tpgzy/p/9057249.html
Copyright © 2020-2023  润新知