威威猫系列故事——篮球梦
Time Limit: 300/100 MS (Java/Others) Memory Limit: 65535/32768 K (Java/Others)
Total Submission(s): 3940 Accepted Submission(s): 1028
Problem Description
威威猫十分迷恋篮球比赛,是忠实的NBA球迷,他常常幻想自己那肥硕的身躯也能飞起扣篮。另外,他对篮球教练工作也情有独钟,特别是对比赛的战术,投篮选择方面也是很有研究,下面就是威威猫研究过的一个问题:
一场NBA篮球比赛总共48分钟,假如我们现在已经知道当前比分
A:B,A代表我方的比分,B代表对方的比分,现在比赛还剩下t秒时间。我们简单的认为双方各自进攻一次的时间皆固定为15秒(不到15秒则进攻不得
分),且为交替进攻,即我方进攻一次,接着对方进攻,依次循环。
进攻有三种选择方式:(这里不考虑命中率)
1、造犯规,(假设都两罚一中)得1分;
2、中距离投篮 得2分;
3、三分球 得3分。
为了简化问题,假设在对方回合,由于我方防守比较好,只让对手得1分,且为固定,即对方的进攻回合就为每回合得1分。现在比赛进入最后关头,接下来第一
个回合是我方进攻,现在威威猫想要知道教练有多少种不同的选择能使我方可能赢得比赛(可能的意思就是不考虑命中率的情况)。
Input
输入有多组数据(不超过250组);
每组数据包含3个整数A,B和t,其中A和B 表示当前的比分(0 <= A, B <= 200),t表示还剩多少时间(单位秒 0 <= t <= 600)。
Output
请输出可行的方案数,每组数据输出占一行。
Sample Input
88 90 50
Sample Output
6
dp[i][j]代表进攻i次得到j分的方案数.
dp[i][j] = dp[i-1][j-1]+dp[i-1][j-2]+dp[i-1][j-3].
然后再去算在进攻次数下得到 m-n+1 -> 3*进攻次数 这么多分情况下所有的得分可能。
#include <stdio.h> using namespace std; typedef long long LL; const int N = 25; int dp[N][3*N]; ///dp[i][j]代表进攻 i 次得到 j 分的方案数,最多也就 600/15/2次机会,分数最多为600/15/2*3分 int main(){ dp[0][0] = dp[1][1] = dp[1][2] = dp[1][3] =1; for(int i=2;i<N;i++){ for(int j=1;j<3*N;j++){ dp[i][j] += dp[i-1][j-1]; ///本次进攻得到1分 if(j>=2) dp[i][j]+=dp[i-1][j-2]; ///本次进攻得到2分 if(j>=3) dp[i][j]+=dp[i-1][j-3]; ///本次进攻得到3分 } } int n,m,t; while(scanf("%d%d%d",&n,&m,&t)!=EOF){ LL ans = 0; int t1,t2; t2 = t/30; t1 = t/15 - t2; m+=t2; ///对方的最终分数 int k = (m-n+1)>0?m-n+1:0; for(int i=k;i<=t1*3;i++){ ans+=dp[t1][i]; } printf("%lld\n",ans); } }