• USACO 2017 January Contest Gold T2: Hoof, Paper, Scissors


    题目大意

    你可能听说过“石头,剪刀,布”的游戏。FJ的牛喜欢玩一个类似的游戏,它们称之为“蹄子,剪刀,布”(“蹄子”就是“石头”)。

    游戏规则很简单:比赛双方同时数到3,然后同时出一个手势,代表“蹄子”“剪刀”或“布”。“蹄子”胜“剪刀”,“剪刀”胜“布”,“布”胜“蹄子”。举个例子,第一头牛出“蹄子”,第二头牛出“布”,则第二头牛胜利。当然,也可以“平局”(如果两头牛手势相同的话)。

    FJ想对阵自己获奖的牛,贝西。贝西作为一个专家,能够预测FJ的手势。不幸的是,贝西作为一头牛,也十分的懒惰。事实上,她只愿意变换固定次数的手势来完成游戏。例如,她可能只想变1次,则他可能出“蹄子”几次,剩下的都出“布”。

    他们一共玩 N  (1N100,000)轮,贝西愿意改变K (0K20)次手势。

    鉴于贝西预测FJ会出的手势,以及她想变的次数,求出她最多能赢多少场

    题目分析

    观察数据范围 N很大,而K极小,所以可以考虑使用关于K来DP。

    令 f[i][j][k] 代表第 i 回合最多换 j 次手势且当前情况下选的 k手势(代表蹄子,剪刀或者布)时赢的最多场次。

    那么转移方程就很显然了,令pk表示手势 i对j 时 对 i 来说的胜负情况,赢为1,输为0

    f[i][j][k] = max( f[i-1][j][k] + pk[k][a[ i ]], f[i-1][j-1][p(不同于k的另外手势)] + pk[k][a[i]] )

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 const int MAXN=1e5+10;
     4 
     5 map<char,int> g; 
     6 int res[5][5];
     7 int n,k,ans;
     8 int a[MAXN],f[MAXN][25][4];
     9 char ch;
    10 inline void Init(){
    11     g['H']=1;g['S']=2;g['P']=3;
    12     res[1][2]=1;res[2][3]=1;res[3][1]=1;
    13 }
    14 int main(){
    15     Init();
    16     scanf("%d%d",&n,&k);
    17     for(int i=1;i<=n;++i){
    18         cin>>ch;
    19         a[i]=g[ch];
    20     }
    21     for(int i=1,x;i<=n;++i)
    22         for(int j=0;j<=min(i,k);++j)
    23             for(int p=1;p<=3;++p){
    24                 x=res[p][a[i]];
    25                 f[i][j][p]=max(f[i-1][j][p]+x,f[i][j][p]);
    26                 for(int q=1;q<=3;++q)
    27                     if(q!=p&&j)
    28                         f[i][j][p]=max(f[i][j][p],f[i-1][j-1][q]+x); 
    29             }
    30     for(int i=1;i<=3;++i)
    31         ans=max(f[n][k][i],ans);
    32     printf("%d
    ",ans);
    33     return 0;
    34 }
  • 相关阅读:
    python基础7
    python基础7
    十大经典预测算法(一)----线性回归
    RNN-循环神经网络
    CNN之经典卷积网络框架原理
    卷积神经网络CNN
    决策树的生成
    欠拟合、过拟合及解决方法
    决策树
    KD树
  • 原文地址:https://www.cnblogs.com/LI-dox/p/11228370.html
Copyright © 2020-2023  润新知