zoukankan      html  css  js  c++  java
  • DP的简单应用

    Problem A:简单的图形覆盖

    Time Limit:1000MS  Memory Limit:65536K
    Total Submit:201 Accepted:104 

    Description 

    有一个2*n的方格,要用若干个1*2的模块覆盖,模块可以横放,也可以竖放.问对于给定的n(n<=100),有多少种不同的覆盖方法.

    Input 

    有多个测试用例,每个用例占一行,为一个正整数n

    Output 

    对于每个测试用例,输出一行相应的结果

    Sample Input 

    9

    11

    Sample Output 

    55

    144

    分析:

    f(n)={ 1  n=1

         2  n=2

       f(n-1)+f(n-2) n>2

    }

     1 #include<stdio.h>
     2 int A[101];
     3 int main()
     4 {
     5    int n,i;
     6    while(scanf("%d",&n)!=EOF)
     7    { 
     8        A[0]=1;A[1]=1;
     9        if(n==1||n==0)  printf("%d
    ",A[0]);
    10        else
    11        {
    12        for(i=2;i<n;i++)
    13            A[i]=A[i-1]+A[i-2]; 
    14        printf("%d
    ",A[i]);
    15        }
    16    }
    17    return 0;
    18 }
    View Code

    递归解决

     1 #include <stdio.h>
     2 #include <string.h>
     3 int A[101];
     4 int f(int n)
     5 {
     6     memset(A,-1,sizeof(A));
     7     if (A[n]!=-1) return A[n];
     8     if(n==0||n==1) 
     9     {
    10         A[n]=1;
    11     }
    12     else
    13     {
    14         A[n]=f(n-1)+f(n-2);
    15         
    16     }
    17     return A[n];
    18 }
    19 int main()
    20 {
    21     int n;
    22     while(scanf("%d",&n)!=EOF)
    23    {       
    24        printf("%d
    ",f(n));
    25    }
    26    return 0;
    27 }
    View Code

    Problem B:最大子段和

    Time Limit:1000MS  Memory Limit:65536K
    Total Submit:574 Accepted:299 

    Description 

    有一组数,-2 5 4 -3 7 的最大子段和是13, 是从57.

    Input 

    第一行输入一个n(1〈 N=100 ) 表示这一组数有多长,第二行是N个数
    测试案例有多个,n=0时结束

    Output 

    输出这一组数的最大子段和.

    Sample Input 

    5

    -2 5 4 -3 7

    10

    9 -3 8 -28 98 -30 -20 50 -24 10

    0

    Sample Output 

    13

    98

    分析:

    A  

    -2

    5

    4

    -3

    7

    表示A0~Ai数段中包含第i个元素的最大子段和

    -2

    5

    9

    6

    13

     

    B[i]={

      A[i]   i=0;

      max{ B[i-1]+A[i] , A[i] } i>0;

    }

     1 #include<stdio.h>
     2 int A[101];
     3 int B[101];
     4 int main()
     5 {
     6    int n,i,max;
     7    scanf("%d",&n);
     8    while(n!=0)
     9    { 
    10        for(i=0;i<n;i++)
    11            scanf("%d",&A[i]);
    12        B[0]=A[0];
    13        for(i=0;i<n;i++)
    14            if(B[i-1]<0) B[i]=A[i];
    15            else
    16                B[i]=B[i-1]+A[i];
    17 /*       max=B[0];   
    18        for(i=1;i<n;i++) if(max<B[i]) max=B[i];
    19        printf("%d
    ",max);
    20        scanf("%d",&n);*/
    21 printf("%d
    ",B[n-1]);
    22 
    23    }
    24    return 0;
    25 }
    View Code

    Problem C:最长公共子序列

    Time Limit:1000MS  Memory Limit:65536K
    Total Submit:164 Accepted:99 

    Description 

    我们称序列Z=是序列X=的子序列当且仅当存在严格上升的序列,使得对j=1,2,...k,有Xij=Zj.比如Z=a,b,f,c是X=a,b,c,f,b,c的子序列.现在给出两个序列X和Y,任务是找到X和Y的最大公共子序列,也就是说要找到一个最长的序列Z,使得Z既是X的子序列也是Y的子序列.

    Input 

    输入包括多组测试数据.每组数据包括一行,给出两个长度不超过200的字符串,表示两个序列.两个字符串之间由若干个空格9.

    Output 

    对每组输入数据,输出一行,给出两个序列的最大公共子序列的长度.

    Sample Input 

    abcfbc  abfcab

    programming contest

    abcd mnp

    Sample Output 

    4

    2

    0

    分析

     

     

    Z[i][j]= {

          0  i=0或j=0;

          Z[i-1][j-1]+1  X[i]=Y[j];

          max{ Z[i-1][j] , Z[i][j-1] }  X[i]!=Y[j]

    }

    下标

     

    0

    1

    2

    3

    4

    5

    6

     

    Z[i][j]

     

    a

    b

    c

    f

    b

    c

    0

     

    0

    0

    0

    0

    0

    0

    0

    1

    a

    0

    1

    1

    1

    1

    1

    1

    2

    b

    0

    1

    2

    2

    2

    2

    2

    3

    f

    0

    1

    2

    2

    3

    3

    3

    4

    c

    0

    1

    2

    3

    3

    3

    4

    5

    a

    0

    1

    2

    3

    3

    3

    4

    6

    b

    0

    1

    2

    3

    3

    4

    4

     

    XY下标从0开始,Z[i][j] 下标有效的从1开始

     

     1 #include<stdio.h>
     2 #include<string.h>
     3 char x[201];
     4 char y[201];
     5 int z[200][200];
     6 int main()
     7 {
     8    int i,j,s,t,max;
     9    while(scanf("%s%s",x,y)!=EOF)
    10    { 
    11        s=strlen(x);t=strlen(y);
    12        for(i=0;i<s;i++)
    13            z[i][0]=0;
    14         for(j=0;j<t;j++)
    15            z[0][j]=0;
    16         for(i=1;i<=s;i++)
    17             for(j=1;j<=t;j++)
    18             {
    19                 if(x[i-1]==y[j-1]) z[i][j]=z[i-1][j-1]+1;
    20                 else 
    21                 {
    22                     if(z[i-1][j]>=z[i][j-1]) z[i][j]=z[i-1][j];
    23                     else   z[i][j]=z[i][j-1];
    24                 }
    25             }
    26 /*        max=z[0][0];
    27         for(i=0;i<=s;i++)
    28             for(j=0;j<=t;j++)
    29                 if(z[i][j]>max) max=z[i][j];*/ 
    30         printf("%d
    ",z[s][t]);
    31    }
    32 
    33    return 0;
    34 }
    View Code

    Problem D:最长上升子序列

    Time Limit:1000MS  Memory Limit:65536K
    Total Submit:456 Accepted:239 

    Description 

    一个数的序列bi,b1<=b2<=b3..<=bn的时候,称这个序列是上升的。对于给定的一个序列(A1,A2,....,AN),可以得到一些上升的子序列(AI1,AI2,....AIK,这里1<=I1<=I2<=....<=IK<=N,比如,对于序列(1,7,3,5,9,4,8),有它的一些上升子序列,(1,7),(3,4,8).这些子序列中最长的长度是4,比如子序列(1,3,5,8). 
    你的任务就是对于给定的序列,求出最长上升子序列的长度

    Input 

    输入有多个案例,每个案例占两行: 
    第一行是序列的长度N(1<=N<=1000).第二行给出序列中的N个整数,这些整数的取值范围都在010000. 

    Output 

    最长上升子序列的长度.

    Sample Input 

    7

    1 7 3 5 9 4 8

    2

    1036 3

    Sample Output 

    4

    1

    分析

    设置b[N]b[i]表示序列的第1个数到第i个数(保留第i个数)的最长上升子序列的长度。

     

    b[i]=max(b[j])+1(a[j]<a[i],1<=j<=i<=n)

    如果a[i]最小,则b[i]=1

     

     

    A

    1

    7

    3

    5

    9

    4

    8

    B

    1

    2

    2

    3

    4

    3

    4

     1 #include<stdio.h>
     2 int A[100],B[100];
     3 int main()
     4 {
     5     int n,i,j,max;
     6     while(scanf("%d",&n)!=EOF)
     7     {
     8         for(i=0;i<n;i++)
     9             scanf("%d",&A[i]);
    10         B[0]=1;
    11         for(i=1;i<n;i++)
    12         {
    13             max=0;
    14             for(j=0;j<i;j++)
    15                 if(A[j]<A[i]&&B[j]>max) 
    16                                    max=B[j];
    17             B[i]= max+1;
    18         }
    19         max=B[0];
    20         for(i=1;i<n;i++)
    21             if(max<B[i]) max=B[i];
    22         printf("%d
    ",max);
    23     }
    24     return 0;
    25 }                            
    View Code

     

  • 相关阅读:
    ETL工具主流产品
    深入了解当前ETL中用到的一些基本技术
    用C#实现通用守护进程
    80端口被system占用的问题
    Python Web 性能和压力测试 multi-mechanize
    [python]用profile协助程序性能优化
    python代码优化技巧
    转:Java学习路线图
    SecureCRT 颜色
    深度学习(Deep Learning)算法简介
  • 原文地址:https://www.cnblogs.com/xuesen1995/p/4113470.html
Copyright © 2011-2022 走看看