动态规划专题

 

 

一、简单基础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\n",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

    +代码在此

 

你可能感兴趣的:(动态规划)