题目标题:
威威猫系列故事--篮球梦
题目链接:
http://acm.hdu.edu.cn/showproblem.php?pid=4504
题目类型:
动态规划
数据结构:
无
思路分析:
既然B队每次的进攻时间跟得分是固定的
那么不如直接吧B的得分先全部加上,
然后简化问题成 A队能不能靠剩下的进攻次数赢B
DP的方法是使用记忆搜索.
建立一个DP[i][j] 来保存 i 代表当前第几次进攻, j 代表目前A的得分
直接DFS一次即可得到答案.
模拟法则可以模拟每次A队进攻的得分范围..
比如A队一开始的分数是88分
那么第一次进攻后
它的得分可能是 89 90 91
第二次可能是 90 91 91 92 92 92 93 93 94..
以此类推,..
最后得到超过B队的分数的个数即可
证明:
略
源代码:
/// DP /
#include <iostream>
#include <stdio.h>
using namespace std;
typedef __int64 int64;
int Ai, Bi;
int A, B, t;
int64 dp[205][205];
int64 _dfs( int p_i, int p_j )
{
if( dp[p_i][p_j] != -1 )
{
return dp[p_i][p_j];
}
if( p_i == Ai )
{
dp[p_i][p_j] = p_j > B ? 1 : 0;
return dp[p_i][p_j];
}
dp[p_i][p_j] = _dfs( p_i + 1, p_j + 1 ) + _dfs( p_i + 1, p_j + 2 ) + _dfs( p_i + 1, p_j + 3 );
return dp[p_i][p_j];
}
int main()
{
while( scanf( "%d%d%d", &A, &B, &t ) != EOF )
{
memset( dp, -1, sizeof( dp ) );
t /= 15;
Bi = t % 2 == 0 ? t / 2 : ( t - 1 ) / 2;
Ai = t % 2 == 0 ? t / 2 : ( t - 1 ) / 2 + 1;
B += Bi;
printf( "%I64d\n", _dfs( 0, A ) );
}
return 0;
}
/ 模拟
#include <iostream>
#include <stdio.h>
#include <map>
using namespace std;
typedef __int64 int64;
int Ai, Bi;
int A, B, t;
struct LMIC_BALL
{
int64 val, update;
};
int main()
{
while( scanf( "%d%d%d", &A, &B, &t ) != EOF )
{
int i, j;
map<int, LMIC_BALL> rlt;
t /= 15;
Bi = t % 2 == 0 ? t / 2 : ( t - 1 ) / 2;
Ai = t % 2 == 0 ? t / 2 : ( t - 1 ) / 2 + 1;
B += Bi;
( rlt[A] ).val = 1;
for( i = A; i < A + Ai; i ++ )
{
for( j = i; j <= A + ( i - A ) * 3; j ++ )
{
rlt[j + 1].update += rlt[j].val;
rlt[j + 2].update += rlt[j].val;
rlt[j + 3].update += rlt[j].val;
}
for( j = i + 1; j <= A + ( i - A ) * 3 + 3; j ++ )
{
rlt[j].val = rlt[j].update;
rlt[j].update = 0;
}
int64 snt = 0;
for( i = A + Ai; i <= A + Ai * 3; i ++ )
{
if( i > B )
{
snt += rlt[i].val;
}
}
printf( "%I64d\n", snt );
}
return 0;
}