HDU5000 (DP + 规律)

题意:举例子好说点,告诉你4个数字,8,6,4,2四个数字,组成一个四位数,如果两个数字分别是1111,2222,则2222会吧1111杀掉,就是组成的四位数不能每一位都小于或等于一个数,然后让你求出最大能够存活的数目。

分析:场上的时候自己一直在找规律,推公式,以为是四个数字递增递减交替的规律,没想到是和是一定的规律,即num/2,和一定了那就是DP了;

PS:  我其实对DP是很发怵的,但是我觉得最起码还是要DP入门!感觉找到规律后这个题目就挺简单的!本来我对DP有个固定看法,那就是贪心能做的题,DP都能做,但是DP能做的,

       贪心有可能做不了,也感觉DP,贪心,推公式,三者联系很密切,有时候找不到规律或者贪不下去就找DP。

 

 1 #include <cstdio>
 2 #include <iostream>
 3 #include <sstream>
 4 #include <cmath>
 5 #include <cstring>
 6 #include <cstdlib>
 7 #include <string>
 8 #include <vector>
 9 #include <map>
10 #include <set>
11 #include <queue>
12 #include <stack>
13 #include <algorithm>
14 using namespace std;
15 #define ll long long
16 #define _cle(m, a) memset(m, a, sizeof(m))
17 #define repu(i, a, b) for(int i = a; i < b; i++)
18 #define repd(i, a, b) for(int i = b; i >= a; i--)
19 #define sfi(n) scanf("%d", &n)
20 #define sfl(n) scanf("%lld", &n)
21 #define pfi(n) printf("%d\n", n)
22 #define pfl(n) printf("%lld\n", n)
23 #define N 6005
24 #define MOD 1000000007
25 int t[N],d[N][N];
26 
27 int main()
28 {
29     int n,T;
30     scanf("%d",&T);
31     while(T--)
32     {
33         scanf("%d",&n);
34         memset(t,0,sizeof(t));
35         int sum = 0;
36         repu(i,0,n)
37         {
38             scanf("%d",&t[i+1]);
39             sum += t[i+1];
40         }
41         sum /= 2;
42         repu(i,0,2001)///初始化
43         repu(j,0,2001)
44         d[i][j] = 0;
45 
46         repu(i,0,t[1]+1)///当只有一个人的时候,和是i,只有一种方案
47         d[1][i] = 1;
48 
49         repu(i,2,1+n)///属性数目
50         {
51             repu(j,0,sum+1)///
52             {
53                 repu(k,0,t[i]+1)
54                 {
55                     if(j < k)
56                         break;
57                     d[i][j] = (d[i-1][j-k] + d[i][j]) % MOD;
58                     ///只需要在前一个的基础上加k,因为和是一定的
59                     ///举例说明,t分别是8 6 4 2
60                     ///目前d[3][10],k等于4,则等于 += d[2][6],则在第四位上+4
61                     ///而且完全可以在第四位上加到满为止
62                 }
63             }
64         }
65         printf("%d\n",d[n][sum]);
66     }
67     return 0;
68 }
DP

看别人代码能明白啥意思,自己写就不知道该怎么分状态。。。

posted @ 2015-08-03 23:48  一麻袋码的玛侬  阅读(242)  评论(0编辑  收藏  举报