笔记-CF578D LCS Again
如果进展不下去了,前往别忘了有写笔记这条路。
想一道题,要么认真想,要么不想。如果是难题的话,在匆忙中想只会降低效率,造成误区。
First DP
设 \(f[i][j]:j\in[0,4)\) 表示第 \(i\) 个字母的状态(\(0\) 表示已经完成,\(1\) 表示和后一个字符匹配,\(2\) 表示和前一个字符匹配,\(3\) 表示与当前字符不匹配,命运暂定)。
好像没人这么做,实现起来也有诸多困难,先把代码放在这里,下次状态好了继续写。
//George1123
#include <bits/stdc++.h>
using namespace std;
typedef long long i64;
typedef unsigned int u32;
typedef unsigned long long u64;
typedef vector<int> vi;
typedef pair<int,int> pii;
#define x first
#define y second
#define sz(a) (int)((a).size())
#define all(a) (a).begin(),(a).end()
#define R(i,n) for(int i=0;i<(n);++i)
#define L(i,n) for(int i=(n)-1;i>=0;--i)
constexpr int inf32=0x3f3f3f3f;
constexpr i64 inf64=0x3f3f3f3f3f3f3f3f;
int main(){
ios::sync_with_stdio(false);
cin.tie(0),cout.tie(0);
int n,m;
string s;
cin>>n>>m>>s;
vector<vi> f(n+1,vi(4,0));
// 0: finished; 1: same as next;
// 2: same as prev; 3: diff with this b
R(i,n){
if(i==n-1||s[i]==s[i+1])
f[i+1][3]+=m-1; //t[i]!=s[i]
else f[i+1][3]+=m-2;
//t[i]!=s[i]&&t[i]!=s[i+1];t[i]=s[i+1]
f[i+1][0]+=f[i][0]; //t[i]=s[i]
f[i+1][2]+=f[i][2]; //t[i]=s[i-1]
f[i+1][2]+=f[i][3]; //t[i]=s[i-1]
if(i) f[i+1][2]+=1; //t[i]=s[i-1]
if(i==n-1){
f[i+1][0]+=f[i][1]*m; //t[i]=any
if(i) f[i+1][0]+=m-1; //t[i]=any
} else {
f[i+1][0]+=f[i][1]*(m-1); //t[i]!=s[i+1]
f[i+1][1]+=f[i][1]; //t[i]=s[i+1]
if(i&&s[i-1]!=s[i+1]){
if(i) f[i+1][0]+=m-2; //t[i]!=s[i+1]
if(i) f[i+1][1]+=1; //t[i]=s[i+1]
} else if(i) f[i+1][0]+=m-1; //t[i]!=s[i+1]
}
if(i&&s[i]!=s[i-1]){
f[i+1][0]+=f[i][2]; //t[i]=s[i]
f[i+1][0]+=f[i][3]; //t[i]=s[i]
}
}
// R(i,n+1)R(j,4) cout<<f[i][j]<<" \n"[j==3];
cout<<f[n][0]+f[n][2]+f[n][3]<<'\n';
return 0;
}
/* stuff you should look for
* int overflow, array bounds
* special cases (n=1?)
* do smth instead of nothing and stay organized
* WRITE STUFF DOWN
* DON'T GET STUCK ON ONE APPROACH
*/
Second 哈希
重要思想:每次删一个字符然后插入,哈希,std::set
。
时间复杂度 \(\Theta(n^2m)\),不能通过。
Third 乱搞
题解。
\[\Huge\rm --AFO--
\]