1. 程式人生 > >2018 Multi-University Training Contest 9

2018 Multi-University Training Contest 9

void multi rain 條件 遞推 close hdu map namespace

Rikka with Nash Equilibrium

題意:

  定義pure strategy Nash equilibriums為矩陣中的一個數並且該數為所在行和列的最大值。現在要求構造一個矩陣,滿足【1,n*m】中的每個數出現且只出現一次在矩陣中,並且矩陣至多只有一個pure strategy Nash equilibriums。問可以構造多少個滿足上述條件的矩陣?

分析:

  首先很容易想到的是從大到小放置這些值並且之後的數要放在之前的數占據的行和列上,因為在這種策略下,當前的數必定不是它所在行和列的最大值(除了n*m),那麽就保證矩陣中至多出現一個pure strategy Nash equilibriums。考慮用dp【i】【j】【k】表示放置了i個數占據j行k列的方案數,不難看出當我們放置一個數後,只可能出現當前占據的行+1,當前占據的列+1或者當前占據的行和列都不變三種情況(不可能同時+1是因為前面規定了之後的數必須放在之前的數占據的行和列上),然後依次遞推下去,最後答案的解就是dp【n*m】【n】【m】。

  參考博客:大佬博客

代碼:

技術分享圖片
#include <queue>
#include <vector>
#include <math.h>
#include <string>
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>

using namespace std;
#define ll long long
#define ull unsigned long long
#define cls(x) memset(x,0,sizeof(x))
#define
clslow(x) memset(x,-1,sizeof(x)) const int maxn=81; int n,m,mod,T; ll dp[maxn*maxn][maxn][maxn]; void add(ll& a,ll b) { a+=b; while(a>=mod) a-=mod; } int main() { #ifndef ONLINE_JUDGE freopen("in.txt","r",stdin); #endif // ONLINE_JUDGE scanf("%d",&T);
while(T--) { scanf("%d %d %d",&n,&m,&mod); cls(dp); dp[1][1][1]=n*m; for(int i=1;i<n*m;i++){ for(int j=1;j<=n;j++){ for(int k=1;k<=m;k++){ if(max(j,k)>i) break; if(!dp[i][j][k]) continue; //如果行+1,首先考慮放在哪一列,然後考慮該列上一共有多少未被占據的行 if(j<n) add(dp[i+1][j+1][k],dp[i][j][k]*k%mod*(n-j)%mod); //列同理 if(k<m) add(dp[i+1][j][k+1],dp[i][j][k]*j%mod*(m-k)%mod); //行列都被占據的位置一共有j*k個,去掉之前放置的數的位置個數i if(i<j*k) add(dp[i+1][j][k],dp[i][j][k]*(j*k-i)%mod); } } } printf("%lld\n",dp[n*m][n][m]); } return 0; }
View Code

Rikka with Stone-Paper-Scissors

題意:

  Yuta有a個剪刀卡片,b個石頭卡片,c個布卡片,Rikka有a1個剪刀卡片,b1個石頭卡片,c1個布卡片(a+b+c=a1+b1+c1),每次猜拳前Rikka都知道Yuta每種卡片的數量,在采取最優策略的條件下,問Rikka贏比賽的次數的期望是多少?

分析:

  考慮對於Rikka和Yuta對局的所有情況中,對於一方的一張卡片都會和對方的所有卡片組合(a+b+c),在這(a+b+c)種情況中,每贏一局則相當於對答案貢獻了1/(a+b+c),輸一局則貢獻-1/(a+b+c)。那麽對於總體,求出一共有多少種贏的情況和輸的情況即可。

代碼:

技術分享圖片
#include <map>
#include <queue>
#include <math.h>
#include <string>
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>

using namespace std;
#define ll long long
#define ull unsigned long long
#define cls(x) memset(x,0,sizeof(x))
#define clslow(x) memset(x,-1,sizeof(x))

const int maxn=1e5+100;

ll a[10],b[10];

int main()
{
    #ifndef ONLINE_JUDGE
        freopen("in.txt","r",stdin);
    #endif // ONLINE_JUDGE
    int T;
    scanf("%d",&T);
    while(T--)
    {
        for(int i=1;i<=3;i++)   scanf("%lld",&a[i]);
        for(int i=1;i<=3;i++)   scanf("%lld",&b[i]);

        ll res=0,sum=0;
        ll win=0,lose=0;
        for(int i=1;i<=3;i++){
            sum+=a[i];
            lose=b[i]*a[i+1>3?1:i+1];
            win=b[i]*a[i-1<1?3:i-1];
            res+=win-lose;
        }
        ll gcd=__gcd(res,sum);
        res/=gcd;sum/=gcd;
        if(res>0&&sum<0){
            res=-res;
            sum=-sum;
        }
        if(res%sum==0)  printf("%lld\n",res/sum);
        else            printf("%lld/%lld\n",res,sum);
    }
    return 0;
}
View Code

Rikka with Badminton

題意:

  已知有a個學生沒有球也沒有拍,b個學生只有拍,c個學生只有球,d個學生有球又有拍。現在安排學生去參賽,比賽成功舉辦的條件是至少有兩個拍和一個球,現在問一共有多少種安排方案使得比賽舉辦失敗?

分析:

  對於每一種情況都討論一下,最後去掉重復計算的情況。

代碼:

技術分享圖片
#include <map>
#include <queue>
#include <math.h>
#include <string>
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>

using namespace std;
#define ll long long
#define ull unsigned long long
#define cls(x) memset(x,0,sizeof(x))
#define clslow(x) memset(x,-1,sizeof(x))

const int maxn=1e5+100;
const int mod=998244353;

int T;
ll a,b,c,d;

ll poww(ll a,ll k)
{
    ll res=1;
    while(k)
    {
        if(k&1) res=res*a%mod;
        a=a*a%mod;
        k>>=1;
    }
    return res;
}

int main()
{
    #ifndef ONLINE_JUDGE
        freopen("in.txt","r",stdin);
    #endif // ONLINE_JUDGE
    scanf("%d",&T);
    while(T--)
    {
        ll ans=1;
        scanf("%lld %lld %lld %lld",&a,&b,&c,&d);
        ///沒拍沒球
        ans=(ans+poww(2,a)-1)%mod;
        ///有拍沒球
        ans=(ans+(poww(2,b)-1)*poww(2,a)%mod)%mod;
        ///沒拍有球
        ans=(ans+(poww(2,c)-1)*poww(2,a)%mod)%mod;
        ///有拍有球
        ans=(ans+d*poww(2,a+c)%mod+b*poww(2,a+c)%mod)%mod;
        ans=(ans-b*poww(2,a)%mod+mod)%mod;
        printf("%lld\n",ans);
    }
    return 0;
}
View Code

2018 Multi-University Training Contest 9