HDU 4972 A simple dynamic programming problem

来源:互联网 发布:久其DNA培训源码 编辑:程序博客网 时间:2024/05/20 04:13

A simple dynamic programming problem

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 78    Accepted Submission(s): 25



Problem Description
Dragon is watching NBA. He loves James and Miami Heat.

Here's an introduction of basketball game:http://en.wikipedia.org/wiki/Basketball. However the game in Dragon's version is much easier:

"There's two teams fight for the winner. The only way to gain scores is to throw thebasketball into the basket. Each time after throwing into the basket, the score gained by the team is 1, 2 or 3. However due to the uncertain factors in the game, it’s hard to predict which team will get the next goal".

Dragon is a crazy fan of Miami Heat so that after each throw, he will write down the difference between two team's score regardless of which team keeping ahead. For example, if Heat's score is 15 and the opposite team's score is 20, Dragon will write down 5. On the contrary, if Heat has 20 points and the opposite team has 15 points, Dragon will still write down 5.

Several days after the game, Dragon finds out the paper with his record, but he forgets the result of the game. It's also fun to look though the differences without knowing who lead the game, for there are so many uncertain! Dragon loves uncertain, and he wants to know how many results could the game has gone?
 

Input
The first line of input contains only one integer T, the number of test cases. Following T blocks, each block describe one test case.

For each test case, the first line contains only one integer N(N<=100000), which means the number of records on the paper. Then there comes a line with N integers (a1, a2, a3, ... , an). ai means the number of i-th record.
 

Output
Each output should occupy one line. Each line should start with "Case #i: ", with i implying the case number. Then for each case just puts an integer, implying the number ofresult could the game has gone.
 

Sample Input
222 341 3 5 7
 

Sample Output
Case #1: 2Case #2: 2
 

Source
2014 Multi-University Training Contest 10


题目链接  :http://acm.hdu.edu.cn/showproblem.php?pid=4972


题目大意  :篮球得分有一分球两分球和三分球,现在记录每次投完两队的分差(当时做的时候队友wa了很多次,因为这里只记录投中的)分差为领先-落后,比如A队10分, B队5分,分差为5,当A队为15, B队20时,分差依旧是5,最后要求最后比赛结果可能的个数值,数据不保证合法,要自己判断


题目分析  :题目坑人。。一个简单动态规划。。。其实简单模拟就行了,关键是两种情况下的公式推导,因为知道最终的分差,两种情况是指最后分差为0和不为0,我们只用考虑双方得分之和有多少种情况,因为每次只能得1,2或者3分,显然只有在分差2 -> 1或者 1 -> 2时有多种可能,比如开始分差为2之后为1,可能A领先B2分,然后B得了1分,这时A领先B1分,或者B得了3分,这时B领先A1分,1 -> 2的情况同理,其它情况的比分只能有一种增量,不改变当前的种类数目,我们可以用count记录相邻为1,2或者2,1得个数,则比分之和有count+1种,
然后看最后一个分差,若是0,则说明A和B打平,这时种类数为count+1若最后分差不为0,显然可能A胜B或者B胜A,有2(count+1)种,还要讨论非法情况,见程序注释

最后举两个简单的例子

2  1  0                                                  A = 2, B = 1 -> A = 2, B = 2
假设初始时两种情况A = 2, B = 0  ->   A = 2, B = 3  -> A = 3, B = 3     两种情况
                                A = 0, B = 2  ->   A = 1, B = 2   -> A = 2, B = 2
                                                            A = 3, B = 2  -> A = 3, B = 3
                                 


2  1  1                                                                          
假设初始时两种情况A = 2, B = 0  ->  A = 2, B = 1 ->   A = 2,B = 3
                                                            A = 2, B = 3 ->   A = 4, B = 3
                                                                                     
假设初始时两种情况A = 0, B = 2  -> A = 1, B = 2  ->  A = 3, B = 3 
                                                           A = 3, B = 2  ->  A = 3, B = 4


#include <cstdio>#define ll long longint const MAX = 100000 + 2;int a[MAX];int main(){    int n, T, flag;    ll ans, count;    scanf("%d",&T);    for(int Ca = 1; Ca <= T; Ca++)    {        count = 0;        flag = 1;        scanf("%d",&n);        for(int i  = 1; i <= n; i++)            scanf("%d",&a[i]);        if(n == 0)        {            //n = 0,平分只有一种情况            printf("Case #%d: 1\n", Ca);            continue;        }        if(a[1] == 0)  //第一次记录时分差不可能为0        {            printf("Case #%d: 0\n", Ca);            continue;        }        for(int i = 1; i <= n - 1; i++)        {            //不合法的情况:            //有一个分差小于0,每两个分差大于3,每两个分差相等且值不为1            if(a[i] < 0 || a[i+1] - a[i] > 3 || a[i] - a[i+1] > 3 || (a[i] == a[i+1] && a[i] != 1) )            {                flag = 3;                break;            }            //记录1 -> 2的情况            if(a[i] == 1)            {                flag = 1;                if(a[i+1] == 2)                     count++;            }            //记录2 -> 1的情况            if(a[i] == 2)            {                flag = 1;                  if(a[i+1] == 1)                     count++;            }        }        //若最后一个分差为0,则为第二种情况,        if(a[n] == 0)             flag = 2;        //用推出的公式计算结果        if(flag == 1)            printf("Case #%d: %I64d\n", Ca, 2 * (count + 1));        else if(flag == 2)            printf("Case #%d: %I64d\n", Ca, count + 1);        else if(flag == 3)            printf("Case #%d: 0\n", Ca);    }}



0 0
原创粉丝点击