传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=4760
【题解】
直接dp,f[i][j][k]表示到了第i个,用了j次改变,上一次出k。
直接转移,压下空间。
# include <stdio.h> # include <string.h> # include <iostream> # include <algorithm> // # include <bits/stdc++.h> using namespace std; typedef long long ll; typedef long double ld; typedef unsigned long long ull; const int M = 5e5 + 10; const int mod = 1e9+7; # define RG register # define ST static int n, K; char opt[3]; int a[M]; // 0 1 2 // 蹄子 剪刀 布 int f[2][23][3]; int main() { cin >> n >> K; for (int i=1; i<=n; ++i) { scanf("%s", opt); if(opt[0] == 'P') a[i] = 2; else if(opt[0] == 'H') a[i] = 0; else a[i] = 1; } int pre = 0, cur = 1; for (int i=1; i<=n; ++i) { for (int j=0; j<=K; ++j) { for (int k=0; k<=2; ++k) { for (int lst=0; lst<=2; ++lst) { if(k == lst) f[cur][j][k] = max(f[cur][j][k], f[pre][j][lst]); else { if(j) f[cur][j][k] = max(f[cur][j][k], f[pre][j-1][lst]); } } f[cur][j][k] += (a[i] == (k+1)%3); } } swap(cur, pre); } int ans = 0; for (int j=0; j<=K; ++j) for (int k=0; k<=2; ++k) ans = max(ans, f[pre][j][k]); printf("%d ", ans); return 0; }