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("\n");
95     }
96     return 0;
97 }
时间: 2024-08-09 08:23:33

POJ 1239 Increasing Sequences(经典的两次dp)的相关文章

POJ 3189 Treats for the Cows(两种DP方法解决)

Treats for the Cows Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 4264   Accepted: 2155 Description FJ has purchased N (1 <= N <= 2000) yummy treats for the cows who get money for giving vast amounts of milk. FJ sells one treat per da

POJ 3258 River Hopscotch 经典二分

点击打开链接 River Hopscotch Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 6189   Accepted: 2683 Description Every year the cows hold an event featuring a peculiar version of hopscotch that involves carefully jumping from rock to rock in a r

POJ 1505 (Copying Books)(经典二分)

Description Before the invention of book-printing, it was very hard to make a copy of a book. All the contents had to be re-written by hand by so called scribers. The scriber had been given a book and after several months he finished its copy. One of

带权并查集(含种类并查集)【经典模板】 例题:①POJ 1182 食物链(经典)②HDU - 1829 A bug&#39;s life(简单) ③hihoCoder 1515 : 分数调查

带权并查集: 增加一个 value 值,并且每次合并和查找的时候需要去维护这个 value 例题一 :POJ 1182 食物链(经典) 题目链接:https://vjudge.net/contest/339425#problem/E 带权并查集的解法 定义两个数组fa[ ]和rela[ ],fa用来判断集合关系,rela用来描述其与根节点的关系.因为关系满足传递性,所以可以推导出给出条件下的当前关系,在判断与之前已有关系是否矛盾. 本题的解法巧妙地利用了模运算,rela数组用0表示同类,1表示当

经典的两种排序算法

一.冒泡排序 int temp = 0; for (int j = 1; j < a.Length; j++) { for (int i = 0; i < a.Length - j; i++)//内循环,每走一趟会把最小值放到最后 { if (a[i] < a[i + 1]) { temp = a[i]; a[i] = a[i + 1]; a[i + 1] = temp; } } } 二.选择法排序 int min; for (int j = 0; j< a.Length; j++

ZOJ 2158 &amp;&amp; POJ 1789 Truck History (经典MST)

链接:http://poj.org/problem?id=1789 或  http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=1158 Description Advanced Cargo Movement, Ltd. uses trucks of different types. Some trucks are used for vegetable delivery, other for furniture, or for br

POJ 1080 Human Gene Functions(求两字符串相似度:LCS变形)

POJ 1080 Human Gene Functions(求两字符串相似度:LCS变形) http://poj.org/problem?id=1080 题意: HDU1080 给你两个由字符A,C,G,T构造的字符串s1和s2, 现在你可以在这两个字符串中插入空格, 使得两串长相等(但是不能使得s1的空格对应s2的空格位置). 然后给你s1的特定字符对应s2中特定字符所能获得的分数矩阵: 问你最后两个字符串所能获得的最大分数是多少? 分析: 本题很类似于求字符串最短编辑距离或者求字符串LCS的

poj 2411 Mondriaan&#39;s Dream(状态压缩+dp)

 题意:用1*2砖块铺满n*m的房间. 思路转自:http://www.cnblogs.com/scau20110726/archive/2013/03/14/2960448.html 因为这道题输入范围在11*11之间,所以可以先打表直接输出.......... 状态压缩DP 经典覆盖问题,输入n和m表示一个n*m的矩形,用1*2的方块进行覆盖,不能重叠,不能越出矩形边界,问完全覆盖完整个矩形有多少种不同的方案 其中n和m均为奇数的话,矩形面积就是奇数,可知是不可能完全覆盖的.接着我们来看

【POJ 3254】 Corn Fields(状压DP)

[POJ 3254] Corn Fields(状压DP) Corn Fields Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 10891   Accepted: 5705 Description Farmer John has purchased a lush new rectangular pasture composed of M by N (1 ≤ M ≤ 12; 1 ≤ N ≤ 12) square parce