uva3363

uva3363

题意是:压缩字符串,,abababa可以压缩为a3(ab),,要是压缩后的字符串尽量短,, 
此题是一个简易的区间DP还是很简单的,,,做完这个题目,,感觉自己的能力上升了不少,,对于区间Dp有了新的理解,, 
Dp[l][r]=min(dp[i][r]+dp[i+1][r],自身压缩后的长度);

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <string>
using namespace std;
char s[205];
int n;
int dp[205][205];


int judge(int l,int r)
{
    int flag,j;
    int tag=0;
     for(int i=1;i<=(r-l+1)/2;i++)
     {
         tag=i;
         flag=0;
         if((r-l+1)%i==0)
         {
             for(int j=l;j<=r-i+1;j=j+i)
             {
                 if(flag==1)
                    break;
                 for(int k=0;k<i;k++)
                 {
                     if(s[l+k]!=s[j+k])
                     {
                         flag=1;
                         break;
                     }
                 }
             }
         }
         else
         {
             flag=1;
         }
         if(flag==0){
         //   printf("tag=====%d\n",tag);
            break;
         }
     }
    // printf("%d  %d  %d\n",l,r,tag);
     if(flag==0)
        return tag;
    else
        return 0;
}

int  check(int l,int r,int pos)
{
    int cnt=-1;
    int qu=(pos-l+1);
     for(int i=pos;i<=r;i+=qu)
     {
         cnt++;
         for(int j=1;j<=pos-l+1;j++)
         {
             if(s[i+j]!=s[l+j-1])
             {
                 return cnt;
             }
         }
     }
     return cnt;
}
int getsum(int k)
{
  int a=0;
  while(k!=0)
  {
      k=(k-k%10)/10;
      a++;
  }
  return a;
}

int Dp(int l,int r)
{
    //printf("%d %d\n",l,r);
    if(dp[l][r]!=0) return dp[l][r];
    if(l==r) {dp[l][r]=1;return 1;}
    int mi=100000;
    for(int i=l;i<r;i++)
    {
        mi=min(mi,Dp(l,i)+Dp(i+1,r));//找到最小的哪一个
    }
   // printf("%d\n",mi);
    int k=judge(l,r);//注意一下自己还可以压缩就ok啦
    if(k){
       int pos=(r-l+1)/k;
       dp[l][r]=min(mi,dp[l][l+k-1]+getsum(pos)+2);//状态转移
    }
    else
        dp[l][r]=mi;//发现自己不能压缩那就老老实实找到最小值吧
    return dp[l][r];
}

int main()
{
    //freopen("in.txt","r",stdin);
    int T;
    scanf("%d",&T);
    while(T--)
    {
        memset(dp,0,sizeof(dp));
        scanf("%s",s+1);
        n=strlen(s+1);
    //    int m=judge(1,n);
      printf("%d\n",Dp(1,n));
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值