60 ( 70 ) pts 求条
查看原帖
60 ( 70 ) pts 求条
602803
_qingshu_楼主2024/4/2 21:22

想法是区间 dp,然后分类讨论寻找第一个折叠之后一定不亏的点来判断是否需要增加折叠花费,但是 WA 了。

#include<bits/stdc++.h>
using namespace std;
string s;
int n,f[5200][5200];
inline bool check(int lef1,int rig1,int lef2,int rig2){
	for(;lef1<=rig1;lef1++,lef2++){
		if(s[lef1]!=s[lef2])return false;
	}
	return true;
} 
int main(){
	cin>>s;n=s.size();s='*'+s;
	for(int len=1;len<=n;len++){
		for(int lef=1;lef<=n-len+1;lef++){
			int rig=lef+len-1;
			f[lef][rig]=rig-lef+1;
			for(int k=lef+rig>>1;k<rig;k++){
				if(k>=lef+rig>>1){
					if(check(2*k-rig+1,k,k+1,rig)){
						if(rig-lef+1>=3*(rig-k)&&check(3*k-2*rig+1,2*k-rig,k+1,rig)){
							if(rig-lef+1>=4*(rig-k)&&check(4*k-3*rig+1,3*k-2*rig,k+1,rig)){
								if(rig-lef+1>=5*(rig-k)&&check(5*k-4*rig+1,4*k-3*rig,k+1,rig)){
									f[lef][rig]=min(f[lef][rig],f[lef][k]);
								}//>=5
								else{
									if(rig-k==1)f[lef][rig]=min(f[lef][rig],f[lef][k-3]+4);
									else f[lef][rig]=min(f[lef][rig],f[lef][k]);	
								}
							}//=4
							else{
								if(rig-k==2)f[lef][rig]=min(f[lef][rig],f[lef][k-4]+5);
								else if(rig-k!=1)f[lef][rig]=min(f[lef][rig],f[lef][k]);
							}//=3
						}//>=3
						else{
							if(rig-k>=3)f[lef][rig]=min(f[lef][rig],f[lef][k]+3);
						}//=2
					}
				}
				f[lef][rig]=min(f[lef][rig],f[lef][k]+f[k+1][rig]);
			}
		}
	}
	cout<<f[1][n];
}

2024/4/2 21:22
加载中...