ZOJ 3329 One Person Game

本文探讨了一种利用动态规划方法优化状态转移过程的技术,通过深入分析状态转移规律,推导出线性表达式并计算系数,最终实现算法效率的提升。详细介绍了算法的实现步骤,包括初始化、递归求解以及最终结果的计算,同时通过实例验证了方法的有效性和实用性。
/*
 期望的状态转移比较容易推出来,我们发现,对于每一个状态转移,总有一项是dp[0],通过观察我们可以发现,任何一个dp[i]均可以表达为dp[0]的线性表达式,最后再推导出系数就可以求解
 */
#include <cstdio>
#include <cstring>
#include <cmath>

int n,k1,k2,k3,a,b,c;
double dp1[555];
double dp2[555];
bool vis[555];


void solve(int loc)//loc<=n
{
    if(vis[loc])  return;
    for(int i=1;i<=k1;i++)
    {
        for(int j=1;j<=k2;j++)
        {
            for(int k=1;k<=k3;k++)
            {
                if(i==a&&j==b&&k==c)
                {
                    dp1[loc]+=1.;
                }
                else
                {
                    if(loc+i+j+k<=n)
                    {
                        solve(loc+i+j+k);
                        dp1[loc]+=dp1[loc+i+j+k];
                        dp2[loc]+=dp2[loc+i+j+k];
                    }
                }
            }
        }
    }
    dp1[loc]/=(double)(k1*k2*k3);
    dp2[loc]/=(double)(k1*k2*k3);
    dp2[loc]+=1.;
    vis[loc]=true;
}

int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d%d%d%d%d%d%d",&n,&k1,&k2,&k3,&a,&b,&c);
        memset(vis,false,sizeof(vis));
        memset(dp1,0,sizeof(dp1));
        memset(dp2,0,sizeof(dp2));
        solve(0);
        //printf("%lf %lf\n",dp1[0],dp2[0]);
        printf("%.15lf\n",dp2[0]/(1.-dp1[0]));
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值