洛谷P1415 拆分数列
Posted fastle
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了洛谷P1415 拆分数列相关的知识,希望对你有一定的参考价值。
题目背景
【为了响应党中央勤节俭、反铺张的精神,题目背景描述故事部分略去^-^】
题目描述
给出一列数字,需要你添加任意多个逗号将其拆成若干个严格递增的数。如果有多组解,则输出使得最后一个数最小的同时,字典序最大的解(即先要满足最后一个数最小;如果有多组解,则使得第一个数尽量大;如果仍有多组解,则使得第二个数尽量大,依次类推……)。
输入输出格式
输入格式:
共一行,为初始的数字。
输出格式:
共一行,为拆分之后的数列。每个数之间用逗号分隔。行尾无逗号。
输入输出样例
输入样例#1:
[1] 3456 [2] 3546 [3] 3526 [4] 0001 [5] 100000101
输出样例#1:
[1] 3,4,5,6 [2] 35,46 [3] 3,5,26 [4] 0001 [5] 100,000101
说明
【题目来源】
lzn改编
【数据范围】
对于10%的数据,输入长度<=5
对于30%的数据,输入长度<=15
对于50%的数据,输入长度<=50
对于100%的数据,输入长度<=500
解析:
进行两次dp第一次dp dp1[i] 表示以第i个数字为结尾的 1~i串的最小结尾串的开始长度
第二次dp dp2[i]表示 以第[i]个数字为开头的开始串的最大长度
然后很显然啊 先第一次找出后面最小的,然后去掉找出的最后的 dp第二次找出前面最大的依次输出即可
当然dp的时候要保持递增性,这个有很多细节,包括去0全0等
(思路及代码均来自candy博客)=.=代码还比他的丑
代码:
#include<cstdio> #include<string> #include<cstring> #include<iostream> #include<algorithm> using namespace std; int n; string s("#"),op; int dp1[1011]; int dp2[1011]; int note[1001]; bool can(int l1,int r1,int l2,int r2) // 其实这两个就是L1 ~R1的一个数字,L2 ~ R2的一个数字 //判断是否是严格递增 { while(l1 <= r1 && note[l1] == 0) { if(l1 == r1)return false; l1++; } while(l2 <= r2 && note[l2] == 0) { if(l2 == r2)return false; l2++; } /**/ int len1 = r1 - l1 + 1; int len2 = r2 - l2 + 1; if(len1 < len2)return true; if(len1 > len2)return false; for(int i = 0;i < len1;i++) { if(note[l1 + i] == note[l2 + i])continue; return note[l1 + i] < note[l2 + i]; } return false;//都相同的情况下 } void dp() { for(int i = 1;i <= n;i++) { dp1[i] = 1; // 向前扩展最多一位(因为他没法不扩展,扩展就可能变大) for(int j = i;j >= 1;j--) if(can(dp1[j - 1],j - 1,j,i)) // { dp1[i] = j;break; } } dp2[dp1[n]] = n;int zz = dp1[n]; while(note[zz - 1] == 0)dp2[zz - 1] = n,zz--; for(int i = dp1[n] - 1;i >= 1;i--) { for(int j = dp1[n] - 1;j >= i;j--) if(can(i,j,j+1,dp2[j + 1])) { dp2[i] = j;break; } } } int main() { cin >> op; s += op; n = s.size() - 1; for(int i = 1;i <= n;i++) note[i] = s[i] - ‘0‘; dp(); int now = 1; while(now <= n) { if(now != 1)printf(","); for(int i = now;i <= dp2[now];i++)printf("%d",note[i]); now = dp2[now] + 1; } return 0; }
以上是关于洛谷P1415 拆分数列的主要内容,如果未能解决你的问题,请参考以下文章