• POJ 1239 Increasing Sequences(经典的两次dp)


    http://poj.org/problem?id=1239

    题意:
    给出一串序列,现在要添加逗号作为分隔符,使得序列是递增序列,然后让最后一个数尽量小,第一个数尽量大。

    思路:
    先从头到尾进行一次dp,d【i】表示分析到第i位时往前的最小长度,这样一来,d【n】就表示最后一位的最小长度。

    在满足了最后一位尽量小的情况下,我们再从尾到头进行一次dp,此时d【i】表示分析到第i位时往后的最大长度。思路和第一次dp是差不多的。

     1 #include<iostream>
     2 #include<algorithm>
     3 #include<cstring>
     4 #include<cstdio>
     5 #include<sstream>
     6 #include<vector>
     7 #include<stack>
     8 #include<queue>
     9 #include<cmath>
    10 #include<map>
    11 #include<set>
    12 using namespace std;
    13 typedef long long ll;
    14 typedef pair<int,int> pll;
    15 const int INF = 0x3f3f3f3f;
    16 const int maxn = 80 + 5;
    17 
    18 int d[maxn];
    19 char s[maxn];
    20 
    21 bool judge(int i, int j, int x, int y)  //判断【i,j】是否大于【x,y】
    22 {
    23     int len1=j-i+1;
    24     int len2=y-x+1;
    25 
    26     while(s[i]=='0')  {i++;len1--;}
    27     while(s[x]=='0')  {x++;len2--;}
    28 
    29     if(len1>len2)  return true;
    30     else if(len1<len2)  return false;
    31     else
    32     {
    33         for(int k=0; k<len1;k++)
    34         {
    35             if(s[k+i]>s[x+k])  return true;
    36             else if(s[k+i]<s[x+k])  return false;
    37         }
    38     }
    39     return false;
    40 }
    41 
    42 int main()
    43 {
    44     //freopen("in.txt","r",stdin);
    45     while(~scanf("%s",s+1))
    46     {
    47         int n=strlen(s+1);
    48         if(n==1 && s[1]=='0')  break;
    49         
    50         //从头到尾找最小长度
    51         for(int i=1;i<=n;i++)
    52         {
    53             d[i]=i;
    54             for(int j=i-1;j>=1;j--)
    55             {
    56                 if(judge(j+1,i,j-d[j]+1,j))
    57                 {
    58                     d[i]=i-j;
    59                     break;
    60                 }
    61             }
    62         }
    63         
    64         //从尾到头找最大长度
    65         int t=n-d[n]+1;   //[t,n]已经是决定了的,不能改变
    66         d[t]=d[n];
    67         for(int i=n-d[n];i>=1;i--)
    68         {
    69             if(s[i]=='0')
    70             {
    71                 d[i]=d[i+1]+1;
    72                 continue;
    73             }
    74             for(int j=t;j>i;j--)
    75             {
    76                 if(judge(j,j+d[j]-1,i,j-1))
    77                 {
    78                     d[i]=j-i;
    79                     break;
    80                 }
    81             }
    82         }
    83 
    84         int tmp=d[1]+1;
    85         for(int i=1;i<=n;i++)
    86         {
    87             if(tmp==i)
    88             {
    89                 printf(",");
    90                 tmp=d[i]+i;
    91             }
    92             printf("%c",s[i]);
    93         }
    94         printf("
    ");
    95     }
    96     return 0;
    97 }
  • 相关阅读:
    前端安全【面试】
    防xss攻击
    前端工程化
    前端项目构建——运维
    react入门
    OpenGL Windows 窗口程序环境搭建
    Django 列的自定义显示
    设计模式之 SOA面向服务的体系
    设计模式之Builder建造者模式 代码初见
    设计模式之Factory工厂模式的好处
  • 原文地址:https://www.cnblogs.com/zyb993963526/p/7255866.html
Copyright © 2020-2023  润新知