Educational Codeforces Round 128 E

E. Moving Chips

首先我们可以发现好像有很多最终位置都能满足最后答案最小的条件
我们再观察可以发现好像两个格子之间的最短曼哈顿距离都是满足这个条件的 那我们自然把最后一列的那个*设为终点最好考虑(后面的直接砍掉即可
然后我们思考如何求这些距离 我们发现只有两行 可以把他拆成4个状态 然后再线性dp即可
我们先把i-1的状态平推到i行状态(i|i-1) 然后再计算一下第i行还可以变出什么花样即可 这样dp才具有完备性

#include <bits/stdc++.h>
using namespace std;
const int N = 2e5+10;
const int M = 998244353;
const int mod = 1000000007;
#define int long long
#define endl '\n'
#define YES cout<<"YES"<<endl;
#define NO cout<<"NO"<<endl;
#define _ 0
#define INF 0x3f3f3f3f3f3f3f3f
#define fast ios::sync_with_stdio(false);cin.tie(nullptr);
int dp[N][4],n;
string s1,s2;
void solve() {
    cin>>n>>s1>>s2;
    s1=')'+s1,s2=')'+s2;
    for(int i=1;i<=n;i++)for(int j=0;j<4;j++)dp[i][j]=INF;
    while(s1.back()=='.'&&s2.back()=='.')n--,s1.pop_back(),s2.pop_back();
    for(int i=1;i<=n;i++){
        int mask=0;
        if(s1[i]=='*')mask+=1;
        if(s2[i]=='*')mask+=2;
        for(int k=0;k<4;k++){
            dp[i][mask|k]=min(dp[i][mask|k],dp[i-1][k]+(k&1)+((k>>1)&1));
        }
        dp[i][1]=min({dp[i][1],dp[i][2]+1,dp[i][3]+1});
        dp[i][2]=min({dp[i][2],dp[i][1]+1,dp[i][3]+1});
    }
    cout<<min(dp[n][1],dp[n][2])<<endl;
}
signed main(){
    fast
    int T;cin>>T;
    while(T--) {
        solve();
    }
    return ~~(0^_^0);
}
posted @ 2022-09-12 19:53  ycllz  阅读(19)  评论(0)    收藏  举报