zoukankan      html  css  js  c++  java
  • Gym 101933E(状态压缩+记忆化搜索)

    传送门

    题面:

    E. Explosion Exploit

    time limit per test

    2.0 s

    memory limit per test

    256 MB

    input

    standard input

    output

    standard output

    In a two player card game, you have nn minions on the board and the opponent has mm minions. Each minion has a health between 11 and 66.

    You are contemplating your next move. You want to play an "Explosion" spell which deals dd units of damage randomly distributed across all minions. The damage is dealt one unit at a time to some remaining minion on the board. Each living minion (including your own) has the same chance of receiving each unit of damage. When a minion receives a unit of damage, its health is decreased by one. As soon as the health of a minion reaches zero, it is immediately removed from the board, before the next damage is dealt. If there are no minions left on the board, any excess damage caused by the spell is ignored.

    Given the current health of all minions, what is the probability that the Explosion will remove all of the opponent's minions? Note that it does not matter if all your own minions die in the process as well, and the damage continues to be dealt even if all your own minions are gone.

    Input

    The first line of input contains the three integers nn, mm, and dd (1≤n,m≤51≤n,m≤5, 1≤d≤1001≤d≤100). Then follows a line containing nn integers, the current health of all your minions. Finally, the third line contains mm integers, the current health of all the opponent's minions. All healths are between 11 and 66 (inclusive).

    Output

    Output the probability that the Explosion removes all the opponent's minions, accurate up to an absolute error of 10−610−6.

    Examples

    input

    Copy

    1 2 2
    2
    1 1
    

    output

    Copy

    0.33333333
    

    input

    Copy

    2 3 12
    3 2
    4 2 3
    

    output

    Copy

    0.13773809

    题意:

        你有n个士兵,敌方有m个士兵,每一个士兵都有一定的血量(最大为6),如果血量归零,则证明该士兵死亡。现在有d点伤害,每一点伤害都会以等概率分配给任意一个人。现在问你,地方的m个士兵全都阵亡的概率。

    题目分析:

        首先我们可以发现,因为每个士兵的血量最大为6,且敌我双方的士兵数均为5,因此我们考虑可以用搜索的方法去解决。

        因为士兵的总血量的状态比较少,因此我们可以考虑用一个12位的long long的每一位去存储每一种血量的个数。此时,这每一个12位的long long整型就唯一代表了一种状态。而又因为在搜索的过程中,每一种曾经访问过的状态所对应的概率必定是唯一的,因此我们只需要用记忆化的形式对曾经出现过的结果记进行记录,以达到剪枝的作用。

        因为我们要记录的是敌军死亡的概率,因此,我们可以优先将敌军的6种血量置于12位long long的高位,这样,当我们访问到的状态值<1000000,则代表已经敌军已经已经死亡,即可直接跳出递归(又一个剪枝)。

        最后只需要将相应的概率相乘并相加即为答案。

    代码:

    #include <bits/stdc++.h>
    using namespace std;
    typedef unsigned long long ll;
    int mp[2][10];
    unordered_map<ll,double>dp;//充当记忆化数组
    ll GetSta(){//获取状态
        ll res=0;
        for(int i=1;i<=6;i++) res*=10,res+=mp[1][i];
        for(int i=1;i<=6;i++) res*=10,res+=mp[0][i];
        return res;
    }
    double dfs(ll sta,int limit){
        if(dp.count(sta)) return dp[sta];//如果该状态曾经访问过,则直接调用结果
        if(sta<1000000) return 1;//如果该状态的值<1000000,则证明敌人已死,返回1
        if(limit==0) return 0;
        int cnt=0;
        for(int i=0;i<2;i++)//获取总人数
            for(int j=1;j<=6;j++) cnt+=mp[i][j];
        double res=0;
        for(int i=0;i<2;i++){
            for(int j=1;j<=6;j++){
                if(!mp[i][j]) continue;
                mp[i][j]--;
                mp[i][j-1]++;
                ll newsta=GetSta();
                double tmp=dfs(newsta,limit-1);//dfs求解下一层的答案
                dp[newsta]=tmp;
    
                mp[i][j]++;//回溯
                mp[i][j-1]--;
    
                res+=1.0*mp[i][j]/cnt*tmp;//统计概率
            }
        }
        return res;
    }
    int main()
    {
        int n,m,d,num;
        scanf("%d%d%d",&n,&m,&d);
        for(int i=0;i<n;i++){
            scanf("%d",&num);
            mp[0][num]++;
        }
        for(int i=0;i<m;i++){
            scanf("%d",&num);
            mp[1][num]++;
        }
        double res=dfs(GetSta(),d);
        printf("%.8f
    ",res);
    }
    
  • 相关阅读:
    Android获取手机型号,系统版本,App版本号等信息
    RFC1939POP3协议中文版
    HDU 1712 01背包 ACboy needs your help
    IOS NSArray 小计
    很有趣的APPLET小程序
    MyEclipse如何显示行数
    e人事管理系统人事档案档案编辑
    2013, VI Samara Regional Intercollegiate Programming Contest
    GB28181视频监控统专题之 相关标准
    基于Golang的http、web服务框架(SSSS)
  • 原文地址:https://www.cnblogs.com/Chen-Jr/p/11007169.html
Copyright © 2011-2022 走看看