• 动态规划专题


    一、简单基础dp

    1、递推:

    hdu 2084 数塔 

     1 #include <iostream>
     2 #include <map>
     3 #include <stack>
     4 #include <deque>
     5 #include <queue>
     6 #include <vector>
     7 #include <set>
     8 #include <algorithm>
     9 #include <cstring>
    10 #include <cstdio>
    11 using namespace std;
    12 const int N=105;
    13 int t, n;
    14 int tow[N][N];
    15 void cal()
    16 {
    17     for(int i=n-2; i>=0; i--)
    18         for(int j=0; j<=i; j++)
    19             tow[i][j]+=max(tow[i+1][j],tow[i+1][j+1]);
    20 }
    21 int main()
    22 {
    23     //freopen("input.txt", "r", stdin);
    24     cin>>t;
    25     while(t--)
    26     {
    27         memset(tow, 0, sizeof(tow));
    28         cin>>n;
    29         for(int i=0; i<n; i++)//输入
    30             for(int j=0; j<=i; j++)
    31                 scanf("%d",&tow[i][j]);
    32         cal();
    33         cout<<tow[0][0]<<endl;
    34     }
    35     return 0;
    36 }
    HDU2084

     hdu 2018 母牛的故事  每年的牛数量=去年的已成年牛*2 + 今年刚好成年的牛*2 + 还未成年的牛。 (假设牛成年时立刻生牛仔)

     1 #include <iostream>
     2 #include <map>
     3 #include <stack>
     4 #include <deque>
     5 #include <queue>
     6 #include <vector>
     7 #include <set>
     8 #include <algorithm>
     9 #include <cstring>
    10 #include <cstdio>
    11 using namespace std;
    12 const int N=56;
    13 int t;
    14 int num[N];
    15 int chi[N];
    16 int bir[N];
    17 void cal()
    18 {
    19     num[1]=1;num[2]=2;num[3]=3;
    20              chi[2]=1;chi[3]=2;
    21              bir[2]=1;bir[3]=1;
    22     for(int i=4; i<N; i++)
    23     {
    24         int tmp1=num[i-1]-chi[i-1];
    25         int tmp2=chi[i-1]-bir[i-3];
    26         num[i]= (tmp1<<1) + (bir[i-3]<<1) + tmp2 ;    //已成年*2 + 刚好成年*2 + 未成年
    27         chi[i]= tmp1 + bir[i-3] + tmp2 ;//已成年+刚好成年+未成年
    28         bir[i]= tmp1 + bir[i-3] ;//已成年+刚好成年
    29 //以上文字表示的全是量,并不是意思。
    30     }
    31 
    32 }
    33 int main()
    34 {
    35     //freopen("input.txt", "r", stdin);
    36     cal();
    37     while(cin>>t,t)
    38         cout<<num[t]<<endl;
    39     return 0;
    40 }
    2048

     hdu 2044 一只小蜜蜂  完全是fabonacci

     1 #include <iostream>
     2 #include <map>
     3 #include <stack>
     4 #include <deque>
     5 #include <queue>
     6 #include <vector>
     7 #include <set>
     8 #include <algorithm>
     9 #include <cstring>
    10 #include <cstdio>
    11 
    12 using namespace std;
    13 const int N=51;
    14 int t, tmp1, tmp2;
    15 long long fab[N];
    16 void cal()
    17 {
    18     fab[0]=fab[1]=1;
    19     for(int i=2; i<N; i++)
    20         fab[i]=fab[i-1]+fab[i-2];
    21 
    22 }
    23 int main()
    24 {
    25     //freopen("input.txt", "r", stdin);
    26     cal();
    27     cin>>t;
    28     while(t--)
    29     {
    30         cin>>tmp1>>tmp2;
    31         cout<<fab[tmp2-tmp1]<<endl;
    32     }
    33 
    34     return 0;
    35 }
    2044

     hdu 2050 折线分割平面  解法看此博客 http://blog.sina.com.cn/s/blog_76eabc150100swg8.html

     1 #include <iostream>
     2 #include <cstdio>
     3 using namespace std;
     4 const int N=10002;
     5 long long a[N];
     6 void cal()
     7 {
     8     a[0]=1;a[1]=2;a[2]=7;
     9     for(int i=3; i<N; i++)
    10         a[i]=(4*i-3)+a[i-1];
    11 }
    12 int main()
    13 {
    14     //freopen("input.txt", "r", stdin);
    15     cal();
    16     int t, i;
    17     cin>>t;
    18     while(t--)
    19     {
    20         scanf("%d",&i);
    21         printf("%d
    ",a[i]);
    22     }
    23     return 0;
    24 }
    HDU2050

     B.working out 用dp预处理4个角,再穷举除了边框外所有的格子,每格有两种可能,最后求出最大。

      1 #include <iostream>
      2 #include <cstdio>
      3 #include <cstring>
      4 using namespace std;
      5 #define ll long long
      6 const int N=1002;
      7 long long a[N][N];
      8 
      9 struct pos
     10 {
     11     ll lef_top;
     12     ll rig_top;
     13     ll lef_bot;
     14     ll rig_bot;
     15 }dp[N][N];
     16 int n, m;
     17 
     18 void cal_dp()
     19 {
     20     //左上
     21     dp[0][0].lef_top=a[0][0];
     22     for(int i=1; i<m; i++)    dp[0][i].lef_top=dp[0][i-1].lef_top+a[0][i];
     23     for(int i=1; i<m; i++)    dp[i][0].lef_top=dp[i-1][0].lef_top+a[i][0];
     24     //左下
     25     dp[n-1][0].lef_bot=a[n-1][0];
     26     for(int i=1; i<m; i++)      dp[n-1][i].lef_bot=dp[n-1][i-1].lef_bot+a[n-1][i];
     27     for(int i=n-2; i>=0; i--)   dp[i][0].lef_bot=dp[i+1][0].lef_bot+a[i][0];
     28     //右上
     29     dp[0][m-1].rig_top=a[0][m-1];
     30     for(int i=m-2; i>=0; i--)   dp[0][i].rig_top=dp[0][i+1].rig_top+a[0][i];
     31     for(int i=1; i<n; i++)      dp[i][m-1].rig_top=dp[i-1][m-1].rig_top+a[i][m-1];
     32     //右下
     33     dp[n-1][m-1].rig_bot=a[n-1][m-1];
     34     for(int i=m-2; i>=0; i--)    dp[n-1][i].rig_bot=dp[n-1][i+1].rig_bot+a[n-1][i];
     35     for(int i=n-2; i>=0; i--)    dp[i][m-1].rig_bot=dp[i+1][m-1].rig_bot+a[i][m-1];
     36 
     37     for(int i=1; i<n; i++)  //左上
     38     {
     39         for(int j=1; j<m; j++)
     40         {
     41             dp[i][j].lef_top=max(dp[i][j-1].lef_top, dp[i-1][j].lef_top)+a[i][j];
     42         }
     43     }
     44 
     45     for(int i=n-2; i>=0; i--)  //左下
     46     {
     47         for(int j=1; j<m; j++)
     48         {
     49             dp[i][j].lef_bot=max(dp[i][j-1].lef_bot, dp[i+1][j].lef_bot)+a[i][j];
     50         }
     51     }
     52 
     53     for(int i=1; i<n; i++)      //右上
     54     {
     55         for(int j=m-2; j>=0; j--)
     56         {
     57             dp[i][j].rig_top=max(dp[i][j+1].rig_top, dp[i-1][j].rig_top)+a[i][j];
     58         }
     59     }
     60 
     61     for(int i=n-2; i>=0; i--)
     62     {
     63         for(int j=m-2; j>=0; j--)
     64         {
     65             dp[i][j].rig_bot=max(dp[i][j+1].rig_bot, dp[i+1][j].rig_bot)+a[i][j];
     66         }
     67     }
     68 
     69 }
     70 
     71 long long enu()
     72 {
     73     //对非外环的所有格子进行穷举
     74     long long ans=0;
     75     for(int i=1; i<n-1; i++)
     76     {
     77         for(int j=1; j<m-1; j++)
     78         {
     79             //左上:往右 左下:往上            //左上:往下 左下:往右
     80             long long tmp1=dp[i][j-1].lef_top+dp[i][j+1].rig_bot+dp[i+1][j].lef_bot+dp[i-1][j].rig_top;
     81             long long tmp2=dp[i-1][j].lef_top+dp[i+1][j].rig_bot+dp[i][j-1].lef_bot+dp[i][j+1].rig_top;
     82             //cout<<tmp1<<" "<<tmp2<<endl;
     83             if( ans<max(tmp1,tmp2) )
     84                 ans=tmp1>tmp2?tmp1:tmp2;
     85 
     86         }
     87     }
     88     return ans;
     89 }
     90 
     91 int main()
     92 {
     93     //freopen("input.txt", "r", stdin);
     94     while(cin>>n>>m)
     95     {
     96         memset(dp,0,sizeof(dp));
     97         for(int i=0; i<n; i++)
     98             for(int j=0; j<m; j++)
     99                 scanf("%d",&a[i][j]);
    100         cal_dp();
    101         cout<<enu()<<endl;;
    102     }
    103     return 0;
    104 }
    CF 429B

     UVA10328  Coin Toss  dp带限制的递推,大数

        +代码在此

    HDU Number String  排列组合数问题,题解戳代码。题不错,技巧性很强。

        +代码在此

    HDU The King’s Ups and Downs  排列组合数问题,题解戳代码

        +代码在此

    二、背包专题

    UVA-624 CD   要记录路径的常规01背包

        +代码在此

    HDU 2955 Robberies 背包容量是double型,寻找其他背包容量。01背包变形。

        +代码在此

    HDU 2602 Bone Collector  最常规的01背包。

        +代码在此

    POJ 3624 Charm Bracelet  最常规的01背包。

        +代码在此

    UVA 562 Dividing coins

        +代码在此

  • 相关阅读:
    北航算法作业三
    水库抽样
    python命名空间
    我说
    Fn键
    windows批处理运行java程序
    Java Sound初探
    java.io.IOException: mark/reset not supported
    三层交换机对链路层数据帧的处理
    北航数值分析作业三
  • 原文地址:https://www.cnblogs.com/xcw0754/p/4461072.html
Copyright © 2020-2023  润新知