现在的位置: 首页 > 综合 > 正文

hdu4504威威猫系列故事——篮球梦(DP)

2013年01月19日 ⁄ 综合 ⁄ 共 948字 ⁄ 字号 评论关闭

题目请戳这里

题目大意:中文题,略。

题目分析:

其实就是求给k个数,每个数可以是1,2,或者3,求这k个数的和大于t 的方案数。

dp[i][j]表示用j个数的和为i的方案数。那么很容易得到转移方程:

dp[i][j] = dp[i - 1][j - 1] + dp[i - 2][j - 1] + dp[i - 3][j - 1]。

即用j个数和为i的方案数为:(用j-1个数和为i-1的方案数,第j个数为1)+(用j-1个数和为i-2的方案数,第j个数为2)+( 用j-1个数和为i-3的方案数,第j个数为3)。

然后就是直接统计输出了。要求的是sigma(dp[i][k]),其中i>t。

第二维可以省掉的样子。

比较基础的dp。。好久没有正儿八经的写dp了。

明显的dp竟然用搜索做,真是作死。。。

征服DP!!

详情请见代码:

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
const int N = 30005;
typedef __int64 ll;
int a,b,last,score;
ll dp[N][55];
ll ans;
ll dpp[N];
int main()
{
    int i,j,t;
    memset(dp,0,sizeof(dp));
    memset(dpp,0,sizeof(dpp));
    dpp[1] = 1;
    for(i = 3;i < N;i ++)
        dpp[i]
    dp[1][1] = dp[2][1] = dp[3][1] = 1;
    dp[2][2] = 1;
    for(i = 3;i < N;i ++)
    {
        for(j = 2;j <= 50;j ++)
            dp[i][j] = dp[i - 1][j - 1] + dp[i - 2][j - 1] + dp[i - 3][j - 1];
    }
    while(scanf("%d%d%d",&a,&b,&t) != EOF)
    {
        last = t / 15;
        b += (last /2 );
        last -= (last /2 );
        score = b - a;
        if(score < 0)
        {
            printf("%I64d\n",(ll)pow(3.0,(double)last));
            continue;
        }
        ans = 0;
        for(i = score + 1;i <= last * 3;i ++)
            ans += dpp[i];// dp[i][last];
        printf("%I64d\n",ans);
    }
    return 0;
}

抱歉!评论已关闭.