求助求助!!!找不到问题啊
查看原帖
求助求助!!!找不到问题啊
698678
zlinda楼主2022/7/28 14:21

本来想发博客的,结果自己过不了就很尴尬

#include<bits/stdc++.h>
using namespace std;
int k,dp[110][110],m[110];
char a[100];
bool check(char a[],int n,int len){
    for(int i=len;i<n;i++)
        if(a[i]!=a[i%len]) return false;
    return true;
}
int main()
{
	int len,i,j,l;
	/*do{
		cin>>a[k];
		k++;
	}while(a[k]!='\n');
	k--;*/
	
	//也可以这样输入(高级) 
	scanf("%s",a);
    k=strlen(a);
	
	for(i=1;i<=9;i++) m[i]=1; 
	for(i=10;i<=99;i++) m[i]=2;
	m[100]=3;//根据数字位数赋初值 
	memset(dp,0x3f,sizeof(dp));//dp[i][j]代表字符串i到j这段最小的长度,初始为无穷大 
	for(i=1;i<=k;i++) dp[i][i]=1;//i,i为1 
	for(int op=2;op<=k;op++)//代表当前判断的这段的长度 
	{
		for(i=0,j=i;j<=i+op-1;i++,j++)//i为左端点,j为右端点,长度为op,所以j<=i+op-1;一次循环做完就使左端点和右端点都右移一位,即i++,j++ 
		{
			for(l=i;l<j;l++)
			dp[i][j]=min(dp[i][j],dp[i][l]+dp[l+1][j]);//分成i-l,和l+1-j
			for(l=i;l<j;l++)//个人感觉可以变成l<=mid,mid=i+j>>1,因为至少分为2段 
			{
				len=l-i+1;//代表要判断的这段的长度 
				if(op%len!=0) continue;//op%len!=0说明不能将i,j分为op/len段 进行下一次循环 
				if(check(a+i,op,len)) dp[i][j]=min(dp[i][j],dp[i][l]+2+m[op/len]);//dp[i][k]是折叠的一段,2是括号,m[op/len]是数字占的位数 
			}
		}
	}
	cout<<dp[0][k-1]<<"\n";
	return 0;
}
2022/7/28 14:21
加载中...