• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
爱白菜的小昆虫
博客园    首页    新随笔    联系   管理    订阅  订阅

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 }

 

posted @ 2014-10-20 09:13  爱白菜的小昆虫  阅读(295)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3