关于区间dp的状态到底是怎么来的
虽然说这个问题看起来很脑残(确实很脑残),但是我一直对dp的状态设计感到云里雾里的,尽管shr_说了要什么就设什么。
今天复习神秘区间dp,发现了很好的题目大概可以作为上述的例子,可以看一篇优秀的文章加深理解
另附本题代码
#include<iostream>
#include<cstring>
using namespace std;
namespace IO{
struct INID{INID(){ios::sync_with_stdio(false),cin.tie(nullptr);}};
static INID INI_D;
inline int gc(){return cin.rdbuf()->sbumpc();}
inline void pc(char c){cout.rdbuf()->sputc(c);}
template<typename T>void rd(T &x){
x=0;int f=1,c=gc();
while('0'>c||c>'9'){if(c=='-')f*=-1;c=gc();}
while('0'<=c&&c<='9'){x=x*10+c-'0';c=gc();}
x*=f;
}template<typename T>void wt(T x){
if(x<0)pc('-');
static int d,tp,stk[40];tp=0;
do{d=x%10;stk[++tp]=(d<0?-d:d)+'0';x/=10;}while(x);
while(tp)pc(stk[tp--]);
}
}using namespace IO;
/*-tpdef------------------------------*/
typedef long long ll;
/*-const------------------------------*/
constexpr int N=205;
/*-def--------------------------------*/
int n;
string s;
int f[N][N][2];
/*-ds---------------------------------*/
/*-alg--------------------------------*/
inline void global(){
}
namespace tqy{
inline void init(){
cin>>s;
n=s.length();
s=' '+s;
memset(f,0x3f,sizeof f);
for(int i=1;i<=n;++i){
f[i][i][0]=1;
// f[i][i]
}
}
inline void solve(){
// if(n<=3){
// cout<<n;
// return;
// }
for(int len=2;len<=n;++len){
for(int i=1;i+len-1<=n;++i){
int j=i+len-1;
f[i][j][0]=len;
if(len%2==0&&s.substr(i,len/2)==s.substr(i+len/2,len/2)){
f[i][j][0]=min(f[i][j][0],f[i][i+len/2-1][0]+1);
}
for(int k=i;k<j;++k){
f[i][j][0]=min(f[i][j][0],f[i][k][0]+j-k);
f[i][j][1]=min(f[i][j][1],min(f[i][k][0],f[i][k][1])+1+min(f[k+1][j][0],f[k+1][j][1]));
}
}
}
cout<<min(f[1][n][0],f[1][n][1]);
}
}
signed main(){
global();
int T=1;
while(T--)tqy::init(),tqy::solve();
return 0;
}
/*
一篇优秀的tj:
https://www.luogu.com.cn/article/2gtyk4q3
*/

浙公网安备 33010602011771号