题目描述

给出一列数字,需要你添加任意多个逗号将其拆成若干个严格递增的数。如果有多组解,则输出使得最后一个数最小的同时,字典序最大的解(即先要满足最后一个数最小;如果有多组解,则使得第一个数尽量大;如果仍有多组解,则使得第二个数尽量大,依次类推……)。

输入输出格式

输入格式:

共一行,为初始的数字。

输出格式:

共一行,为拆分之后的数列。每个数之间用逗号分隔。行尾无逗号。

输入输出样例

输入样例#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


《拆分数列》解题报告

By lzn 动态规划常规题。

第一步先求出最后的那个数最小为多少。(为了叙述方便,记T(i,j)表示从原数列下标i取到j的数字组成的数。)只需正向dp一次,dp1[i]表示前i个数字分成任意多个递增数且最后的数最小时,最后的数为T(dp1[i],i)。则dp1[i]=max(j),(T(dp1[j-1],j-1)<T(j,i))。

第二步要求最后一个数确定的情况下,前面的数字按字典序尽量大的解。类似上面的方法反向动归一次即可。

算法复杂度o(l^3)。由于数据大部分为随机,实际运行效率接近l^2。

 #include<cstdio>
#include<cstring>
#include<iostream>
#include<string>
using namespace std; const int maxn=; string str;
int a[maxn],n,dP[maxn],Dp[maxn]; bool cmp(int l1,int r1,int l2,int r2){
while(l1<=r1&&a[l1]==) l1++;
while(l2<=r2&&a[l2]==) l2++;
int le1=r1-l1+,le2=r2-l2+;
if(le1==||le2==) return ;
if(le1!=le2) return le1<le2;
for(int i=;i<le1;i++)
if(a[l1+i]!=a[l2+i]) return a[l1+i]<a[l2+i];
return ;
} //dP[i]=max(j),(T(dP[j-1],j-1)<T(j,i))
void DP1(){
for(int i=;i<=n;i++){
dP[i]=;
for(int j=i;j;j--)
if(cmp(dP[j-],j-,j,i)){
dP[i]=j;
break;
}
// printf("dP[%d] = %d\n",i,dP[i]);
}
} //Dp[i]=max(j) (T(i,j)<T(j+1,f[j+1]))
void DP2(){
Dp[dP[n]]=n;
for(int i=dP[n];a[i-]==;i--) Dp[i-]=n; for(int i=dP[n]-;i;i--){
for(int j=dP[n]-;j>=i;j--)
if(cmp(i,j,j+,Dp[j+])){
Dp[i]=j;
break;
}
// printf("Dp[%d] = %d\n",i,Dp[i]);
}
} void print(int l,int r){
for(int i=l;i<=r;i++)
putchar(a[i]+'');
} void print(){
print(,Dp[]);
int pos=Dp[]+;
while(pos<=n){
putchar(',');
print(pos,Dp[pos]);
pos=Dp[pos]+;
}
} int main(){
cin>>str; n=str.length();
for(int i=;i<n;i++) a[i+]=str[i]-'';
DP1(); DP2();
print();
return ;
}

luoguP1415 拆分数列 [dp]的更多相关文章

  1. [luoguP1415] 拆分数列(DP)

    传送门 t(i,j)表示下标从i到j的数 d[i]表示以i结尾的最小的数的下标 d[i]=max(j) (1<=j<=i && t(d[j-1],j-1)<t(j,i ...

  2. P1415 拆分数列 DP

    传送门: 题意: 将一个数字串分成许多不同的小串,使得这些小串代表的数字严格递增,要求最后一个数字尽可能地小. 然后满足字典序尽可能大. 思路: 由于最后一个数字要尽可能地小,所以先处理出每个数的L[ ...

  3. 洛谷P1415 拆分数列[序列DP 状态 打印]

    题目背景 [为了响应党中央勤节俭.反铺张的精神,题目背景描述故事部分略去^-^] 题目描述 给出一列数字,需要你添加任意多个逗号将其拆成若干个严格递增的数.如果有多组解,则输出使得最后一个数最小的同时 ...

  4. 洛谷 P1415 拆分数列 解题报告

    拆分数列 题目背景 [为了响应党中央勤节俭.反铺张的精神,题目背景描述故事部分略去^-^] 题目描述 给出一列数字,需要你添加任意多个逗号将其拆成若干个严格递增的数. 如果有多组解,则输出使得最后一个 ...

  5. 洛谷P1415 拆分数列(dp)

    题目链接:传送门 题目: 题目背景 [为了响应党中央勤节俭.反铺张的精神,题目背景描述故事部分略去^-^] 题目描述 给出一列数字,需要你添加任意多个逗号将其拆成若干个严格递增的数.如果有多组解,则输 ...

  6. 洛谷P1415 拆分数列

    题目背景 [为了响应党中央勤节俭.反铺张的精神,题目背景描述故事部分略去^-^] 题目描述 给出一列数字,需要你添加任意多个逗号将其拆成若干个严格递增的数.如果有多组解,则输出使得最后一个数最小的同时 ...

  7. BZOJ 2431: [HAOI2009]逆序对数列( dp )

    dp(i,j)表示1~i的全部排列中逆序对数为j的个数. 从1~i-1的全部排列中加入i, 那么可以产生的逆序对数为0~i-1, 所以 dp(i,j) = Σ dp(i-1,k) (j-i+1 ≤ k ...

  8. BZOJ2431:[HAOI2009]逆序对数列(DP,差分)

    Description 对于一个数列{ai},如果有i<j且ai>aj,那么我们称ai与aj为一对逆序对数.若对于任意一个由1~n自然数组成的 数列,可以很容易求出有多少个逆序对数.那么逆 ...

  9. P1415 拆分数列

    传送门 DP数列长度过大无法枚举,考虑DP设f1[i]储存以第i个字符为结尾时,的最后一个数最小时,这个数的开头的位置(很难想有木有)OK,状态有了,方程想一想就出来了:设$num[i][j]$为数列 ...

随机推荐

  1. 【leetcode】bash脚本练习

    [192]Word Frequency Write a bash script to calculate the frequency of each word in a text file words ...

  2. day03 python数据类型 数字 字符串 布尔

    day03 python   一.基本数据类型     1.int a= 8 a_length = a.bit_length()  #此方法求数字的二进制长度  print(a_length)     ...

  3. nodejs 进阶:图片裁剪

    demo 图片: 效果: var fs = require('fs'); var gm = require('gm'); gm("./不饿.jpg").crop(100,100,2 ...

  4. Dart编程实例 - 类型测试操作符is

    Dart编程实例 - 类型测试操作符is void main() { int n = 2; print(n is int); } 本文转自:http://codingdict.com/article/ ...

  5. 树分基础 bzoj 1468

    我们对于一棵树,我们找一个根,然后统计过这个点的路径有多少符合要求.怎么搞呢?我们可以先维护一个数据结构,然后把先把根作为一个距离自己为0的点放进去,然后对于每一棵子树,先找出所有的与之前的数据结构的 ...

  6. BZOJ 3159: 决战 解题报告

    BZOJ 3159: 决战 1 sec 512MB 题意: 给你一颗\(n\)个点,初始点权为\(0\)的有跟树,要求支持 Increase x y w 将路径\(x\)到\(y\)所有点点权加上\( ...

  7. 逆向思维——cf1241D

    /* 给定一个序列a,每次可以把值为x的所有元素放到a的首部或尾部,问将a变为lis的最少操作步数 对原序列离散化后重新打标记, 可以反着来考虑这个问题:即固定连续的元素值为[l,r]的点不动,那么剩 ...

  8. 转载-NX11.0二次开发新增Spreadsheet相关类的用法!

    这几天搜NX对EXCAL读取写入相关的开发内容,发现唐工写了一篇关于NX11对EXCAL操作的文章.让我知道NX11新增了对EXCAL操作相关的类,以前NX里是没有的.我以前都是用OLE方式去做,没用 ...

  9. SQL生成 C# Model

    本文转自: https://www.cnblogs.com/jhli/p/11552105.html declare @TableName sysname = 'T_FakeOrderList' de ...

  10. PAT_A1070#Mooncake

    Source: PAT A1070 Mooncake (25 分) Description: Mooncake is a Chinese bakery product traditionally ea ...