94pts求调
查看原帖
94pts求调
745929
Komeijizen楼主2024/12/25 16:30

wa on #6#13#16.
UVA上的双倍经验都过了,所以看来是字典序最大的问题.

#include<bits/stdc++.h>
using namespace std;
namespace IO{
	char ibuf[(1<<20)+1],*iS,*iT;
	#ifndef LOCAL
	#define gh() (iS==iT?iT=(iS=ibuf)+fread(ibuf,1,(1<<20)+1,stdin),(iS==iT?EOF:*iS++):*iS++)
 	#else
	#define gh() getchar()
	#endif
	inline long long read(){char ch=gh();long long x=0;bool t=0;while(ch<'0'||ch>'9')   t|=ch=='-',ch=gh();while(ch>='0'&&ch<='9') x=x*10+(ch^48),ch=gh();return t?-x:x;}
	inline void write(int x){static int sta[35];int top = 0;do{sta[top++] = x % 10, x /= 10;} while (x);while (top)putchar(sta[--top] + 48);}
	const void File(bool b1,bool b2){if(b1)freopen("out.out","w",stdout);if(b2)freopen("in.in","r",stdin);}
	
}
using namespace IO;
string s;
int n;
char A[105];
int dp[105][105],mid[105][105];

int getlen(int x){
    int res=0;
    while(x){
        res++,x/=10;
    }
    return res;
}
struct node{
    int typ,rep;//typ=1->从头到尾缩掉了并带有数字.
    int l,r,len,cst;//l,r->循环节
    int tim,truc=0;
    node(){}
    node(int _l,int _r){
        l=_l,r=_r,rep=0,tim=1;
        //len=r-l+1;
        len=dp[l][r];
        cst=len+2+getlen(tim);
    }
    node(int _l,int _r,int _tim){
        l=_l,r=_r,rep=0,tim=_tim;
        len=dp[l][r];
        cst=len+2+getlen(tim);
    }
}fr[105][105];
#define cur fr[i][i+k]
bool equ(int l1,int r1,int l2,int r2){
    if(r1-l1!=r2-l2)return 0;
    for(int i=l1,j=l2;i<=r1;i++,j++){
        if(A[i]!=A[j])return 0;
    }return 1;
}

void output(int l,int r){
    if(r<l)return;
    if(r==l){cout<<A[l];return;}
    if(fr[l][r].tim>1 and fr[l][r].cst==dp[l][r] and dp[l][r]<r-l+1){
        cout<<fr[l][r].tim<<'(';
        output(fr[l][r].l,fr[l][r].r);
        cout<<')';
        return;
    }
    if(fr[l][r].truc){
        output(l,fr[l][r].truc);
        output(fr[l][r].truc+1,r);
        return;
    }
    for(int i=l;i<=r;i++)cout<<A[i];
}
int main(){
    cin>>s;
    n=s.size();
    for(int i=1;i<=n;i++)A[i]=s[i-1];
    for(int i=1;i<=n;i++){
        dp[i][i]=1;
        fr[i][i]=node(i,i);
    }
    for(int k=1;k<n;k++){
        for(int i=1;i<=n-k;i++){//[i,i+k].
            dp[i][i+k]=k+1;
            fr[i][i+k]=node(i,i+k);
            int l=i,r=i+k;
            for(int j=i;j<i+k;j++){//从这个位置分割开,让两边的相匹配.
                node u=fr[i][j],v=fr[j+1][i+k];
                if(equ(u.l,u.r,v.l,v.r)){
                    int tn=(u.tim+v.tim),xn=2+(dp[u.l][u.r])+getlen(tn);
                    if(dp[i][i+k]>=xn){
                        dp[i][i+k]=xn;
                    }
                    cur=node(u.l,u.r,tn);//fr中的是强制匹配的结果,而dp是最小结果.
                }
                if(dp[i][j]+dp[j+1][i+k]<dp[i][i+k]){
                    dp[i][i+k]=dp[i][j]+dp[j+1][i+k];
                    cur=node(i,i+k);
                    cur.truc=j;
                }
            }

        }
    }
    output(1,n);
}
2024/12/25 16:30
加载中...