HDU 4504 威威猫系列故事——篮球梦(dp)

http://acm.hdu.edu.cn/showproblem.php?pid=4504

 

题目大意:

  中文都看得懂。不过我是看hint才正确理解什么意思的。开始的时候理解错了。

解题思路:

  给定时间最多是600,最多进攻次数600/15=40次,我方进攻次数40/2=20次。如果深度搜索多少种情况,

那么时间复杂度是O(3^20),直接就超时了。

  我知道要动态规划,但是自己dp不行,所以就看了网上别人的解题报告。

dp[i][j]=dp[i-1][j-1]+dp[i-1][j-2]+dp[i-1][j-3] ;表示第i次,得j分的方案

 

先将得分方案预处理(预处理时间是O(20*60))。求答案的时候再将进攻t次,大于A、B分数之的方案加起来(时间复杂度最坏O(60))。

 

AC代码:

 1 #include<cstdio>

 2 #include<cstring>

 3 

 4 #define TIMES 21//最多打600/15/2=20次

 5 #define SCORE 61//做多得分20*3=60分

 6 

 7 typedef __int64 LL;

 8 

 9 //dp[i][j] 表示第i次,投j分的情况 dp[i][j]=dp[i-1][j-1]+dp[i-1][j-2]+dp[i-1][j-3]

10 int dp[TIMES][SCORE];

11 

12 void dynamic(){

13 //    memset(dp, 0, sizeof(dp));

14     dp[0][0] = 1;

15     for(int i = 1; i < TIMES; ++i){

16         dp[i][i] = dp[i - 1][i - 1];

17         dp[i][i + 1] = dp[i - 1][i - 1] + dp[i - 1][i];

18 

19         for(int j = i + 2; j <= i * 3; ++j){

20             dp[i][j] = dp[i - 1][j - 1] + dp[i - 1][j - 2] + dp[i - 1][j - 3];

21         }

22     }

23 }

24 

25 int main(){

26     dynamic();//预处理

27     int a, b, t;

28     while(~scanf("%d%d%d", &a, &b, &t)){

29         t /= 15;//

30         b += t / 2;//B队的最终得分

31         t = (t + 1) / 2;//A队还能进攻t次

32         a = b - a + 1;//计算A队至少还差多少分就能赢得比赛

33 

34         if(a < 0) a = 0;//说明A已经赢得比赛 那就把所有的情况加起来

35 

36         LL ans = 0;

37         for(int i = a; i <= t * 3; ++i){//A队进攻t次数 分数>=a的情况加起来

38             ans += dp[t][i];

39         }

40         printf("%I64d\n", ans);

41     }

42     return 0;

43 }

 

你可能感兴趣的:(HDU)