Luogu P1136 迎接仪式 (线性DP,细节)

image

  • 较强限制:"jz"才有贡献; 交换操作。
  • 考虑DP:考虑缩小规模->那么dp数组要维护一个 前i个字母,交换了k次,当前的数交不交换。但是如果 pos1和pos2是互相交换的,但是这俩位置会计入k两次,所以把交换了k次变成'j'字母交换了j次,'z'字母交换了l次数。这个状态方程好像没问题,但是转移过程中会出现非法转移:
    f[i][0][0][0] = max(f[i][0][0][0], f[i - 1][0][0][1]); //j,l都为0, i-1是翻转的,这对么?
  • 不再使用当前位是否翻转这个状态,换一个更为稳妥地:
    我们设f[i][j][k][0]为遍历了字符串的前ii位,改变了jj个jj和kk个zz,并且当前的这一位为jj所能达到的最大价值

设f[i][j][k][1]为遍历了字符串的前ii位,改变了jj个jj和kk个zz,并且当前的这一位为zz所能达到的最大价值

  • 这题最终j和k必须用的次数一样多才合法,要是f[0][100][100][0] 这样肯定是不对的,后面状态从此转移的话j实际用了50次,k90次,也是会被转移到k=100,j =100的,起始合法状态只有f[0][0][0][1] = 0; (0位其实是没有字母的让他为z也不会有贡献)

总结:1. 明确方程的定义!: 容易想出的方程可能会有非法转移,考虑到它。或者更改方程。
2. 本题中jk必须相等,所以要规定唯一合法起始

#include<bits/stdc++.h>
using namespace std;
#define IOS ios::sync_with_stdio(false) ,cin.tie(0), cout.tie(0);
//#pragma GCC optimize(3,"Ofast","inline")
#define ll long long
typedef __int128_t li;
//#define int long long
#define PII pair<int, int>
const int N = 5e2 + 5;
const int M = 1e2 + 5;
const int INF = 0x3f3f3f3f;
const ll LNF = 0x3f3f3f3f3f3f3f3f;
const int mod = 998244353;
const double PI =  acos(-1.0);
int f[N][M][M][2];
int main () {
    int n, k; cin >> n >> k;
    string ss; cin >> ss; ss = "*" + ss;
    memset(f, -0x3f, sizeof f);
    f[0][0][0][1] = 0; 
    int ans = 0;
    for ( int i = 1; i <= n; ++ i ) {
        for ( int j = 0; j <= k; ++ j ) {
            for ( int l = 0; l <= k; ++ l ) {

                if(ss[i] == 'z') {
                    f[i][j][l][1] = max(f[i - 1][j][l][1], f[i - 1][j][l][0] + 1);
                    if(l) f[i][j][l][0] = max(f[i - 1][j][l - 1][0], f[i - 1][j][l - 1][1]);
                } else {
                    f[i][j][l][0] = max(f[i - 1][j][l][1], f[i - 1][j][l][0]);
                    if(j) f[i][j][l][1] = max(f[i - 1][j - 1][l][0] + 1, f[i - 1][j - 1][l][1]);
                }
  
            }
        }
    }
    

    
    for(int i=0;i<=k;i++){
        ans=max(ans,max(f[n][i][i][1],f[n][i][i][0]));
    }
    cout << ans << endl;
    return 0;
}
posted @ 2022-04-13 20:40  qingyanng  阅读(17)  评论(0编辑  收藏  举报