zoukankan      html  css  js  c++  java
  • bzoj3191卡牌游戏

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3191

    原本想模拟过程,从t个人推到1个人;

      但是怎么转移呢?想状压,可是50位压不到角标里。

      那就随便转移吧,把当前人的生存方案数加给所有有可能成为下一轮中自己的人。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #define ll long long
    using namespace std;
    const int N=55;
    int n,m,a[N];
    ll dp[N][N],sum;
    int main()
    {
        scanf("%d%d",&n,&m);
        for(int i=1;i<=m;i++)scanf("%d",&a[i]);
        dp[n][1]=1;
        for(int t=n;t>1;t--)
            for(int i=1;i<=n;i++)
                if(dp[t][i])
                {
    //                printf("t=%d i=%d dp=%d
    ",t,i,dp[t][i]);
                    for(int j=1;j<=m;j++)
                    {
                        int c=a[j]%t,l=i+c+1,r=i-(t-c-1);
    //                    printf("i=%d aj=%d l=%d r=%d
    ",i,a[j],l,r);
                        if(l>r)for(int k=1;k<=n;k++)if(k>=r||k<=l)dp[t-1][k]+=dp[t][i];
                        else for(int k=l;k<=r;k++)
                            dp[t-1][k]+=dp[t][i];
                    }
                }
        for(int i=1;i<=n;i++)sum+=dp[1][i];
        for(int i=1;i<=n;i++)
            printf("%.2lf",(double)dp[1][i]*100/(double)sum),cout<<"% ";
        return 0;
    }
    View Code

    这当然是不对的。那个“有可能成为下一轮中自己的人”不能保证就是下一轮中的自己。

    那怎么办?看看TJ,发现大家是用相对编号来记录下一轮中的自己是哪个人的。

      用记忆化搜索可以想得更灵活一点。以后尝试用这个角度思考。不然自己容易想不出来……

    概率不用每一步都算好。可以之前一直算的是方案数,最后再换算成概率。有时候这样比较方便。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    using namespace std;
    const int N=55;
    int n,m,a[N];
    bool vis[N][N];
    double dp[N][N],sum;
    double sol(int i,int j)
    {
        if(vis[i][j])return dp[i][j];vis[i][j]=1;
        if(i==1)return dp[i][j]=1;
        for(int k=1;k<=m;k++)
            if(a[k]%i!=j%i)//j%i,不是j (j==i)
                dp[i][j]+=sol(i-1,(j-(a[k]%i)+i)%i);
    //    dp[i][j]/=m;
        return dp[i][j];
    }
    int main()
    {
        scanf("%d%d",&n,&m);
        for(int i=1;i<=m;i++)scanf("%d",&a[i]);
        for(int i=1;i<=n;i++)sum+=sol(n,i);
        for(int i=1;i<=n;i++)
        {
            printf("%.2lf%%",sol(n,i)/sum*100);
            if(i!=n)printf(" ");
        }
        return 0;
    }
  • 相关阅读:
    [GXYCTF2019]BabyUpload
    [GYCTF2020]Blacklist
    [极客大挑战 2019]HardSQL
    PHP实现MVC框架路由功能模式
    色环电阻的阻值识别
    python的内存回收机制
    配置Openfiler做ISCS实验
    windows server 2008r2 在vmware里自动关机
    VMware Workstation网络修改vlan id值
    linux的服务自动启动的配置
  • 原文地址:https://www.cnblogs.com/Narh/p/9132643.html
Copyright © 2011-2022 走看看