P6120 USACO S
原题传送门:USACO原题
洛谷传送门: P6120
题意
无非就是石头剪刀布,甚至连规则都没有变
P = 布
H = 石头
S = 剪刀
具体规则就不多赘述了。
给出FJ的所有手势,假设奶牛只能更换一次手势,最多能赢几局(不计平局)
解题思路
立马想到了用前缀和进行维护。
首先计算FJ在石头、剪刀、布三种手势下每次的输赢情况,然后用一维前缀和统计前i次和后n-i次不同的手势组合下的赢的次数,最后统计赢的次数的最大值。
PS: 交完之后我才发现并没有考虑不换手势的情况,但是还是过了(雾
代码
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef vector<int> vi;
typedef set<int> si;
#define PB push_back
const int N = 100005;
int n;
int h[N],p[N],s[N],ans[7];
//p是布,H是石头,S是剪刀
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cin>>n;
char a;
//统计对局情况
for(int i=1;i<=n;i++){
cin>>a;
s[i]=s[i-1];
p[i]=p[i-1];
h[i]=h[i-1];
if(a=='P')s[i]++;
if(a=='H')p[i]++;
if(a=='S')h[i]++;
}
//前缀和计算
for(int i=1;i<=n;i++){
//石头+剪刀,剪刀+石头
ans[1]=max(ans[1],h[i]+s[n]-s[i]);
ans[2]=max(ans[2],s[i]+h[n]-h[i]);
//石头+布, 布+石头
ans[3]=max(ans[3],h[i]+p[n]-p[i]);
ans[4]=max(ans[4],p[i]+h[n]-h[i]);
//剪刀+布,布+剪刀
ans[5]=max(ans[5],s[i]+p[n]-p[i]);
ans[6]=max(ans[6],p[i]+s[n]-s[i]);
}
sort(ans+1,ans+7);
cout<<ans[6]<<endl;
}
完结撒花