洛谷 P3609 [USACO17JAN]Hoof, Paper, Scissor蹄子剪刀…

题目链接

dp[i][j][k] 表示 到第i局,总共变化 j次, 最后出 k的最多赢次数

枚举前一局的出的手 t, 考虑与前一局有没有变化即可转移

非常朴素的DP

[Code]

#include <bits/stdc++.h>
using namespace std;

int read(){
	int x=0,flag=1; char c;
	for(c=getchar();!isdigit(c);c=getchar()) if(c=='-') flag=-1;
	for(;isdigit(c);c=getchar()) x=((x+(x<<2))<<1)+(c^48);
	return x*flag;
}

int n,m;
int a[100005];
int dp[100005][25][3];

int check(int x,int y){
    if(y==0&&x==2) return 1;
    if(y==1&&x==0) return 1;
    if(y==2&&x==1) return 1;
    return 0;
}

int main() {
    n=read(),m=read();
    for(int i=1;i<=n;i++){
	    char c;
	    scanf(" %c",&c);
	    if(c=='P') a[i]=0;
	    if(c=='S') a[i]=1;
	    if(c=='H') a[i]=2;
	}
	int maxx=0;
	for(int p=1;p<=n;p++)
	for(int i=0;i<=m;i++)
	for(int j=0;j<=2;j++){
	    int win=check(a[p],j);
	    
	    for(int t=0;t<=2;t++)
	    if(t==j) dp[p][i][j]=max(dp[p][i][j],dp[p-1][i][j]);
	    else dp[p][i][j]=max(dp[p][i][j],dp[p-1][i-1][t]);
	    
	    dp[p][i][j]+=win;
	    maxx=max(maxx,dp[p][i][j]);
	}
	printf("%d
",maxx);
	return 0;
}



原文地址:https://www.cnblogs.com/zzhzzh123/p/12220727.html