• 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
    ", ans);
    41     }
    42     return 0;
    43 }
  • 相关阅读:
    【bzoj2006】超级钢琴
    【bzoj4940】这是我自己的发明
    【arc076E】Connected?
    【agc004C】AND Grid
    选举
    几何
    打击目标
    【CF Gym100228】Graph of Inversions
    【CodeChef】Chef and Graph Queries
    大包子玩游戏
  • 原文地址:https://www.cnblogs.com/xuqiulin/p/4036444.html
Copyright © 2020-2023  润新知