传送门

t(i,j)表示下标从i到j的数

d[i]表示以i结尾的最小的数的下标

d[i]=max(j) (1<=j<=i && t(d[j-1],j-1)<t(j,i))

这样从1到n一遍DP可以求出末尾最小的数

f[i]表示以i开头的最大的数的下标

f[i]=max(j) (i<=j<=n && t(i,j)<t(j+1,d[j+1]))

边界为f[d[n]]=n

这样从d[n]-1到1一遍DP可以求出开头最大的数,第二个最大的数。。。

注意前导0的情况

#include <cstdio>
#include <cstring>
#define N 1001 int n;
char s[N];
int d[N], f[N];
//d[i]表示以i结尾的数,满足条件的最小数
//f[i]表示以i开头的数,满足条件的最大数
//s[i][j]表示从i到j的数是多少 inline int cmp(int x1, int y1, int x2, int y2)
{
int i, j;
while(s[x1] == '0') x1++;
while(s[x2] == '0') x2++;
if(y1 - x1 == y2 - x2)
{
for(i = x1, j = x2; i <= y1; i++, j++)
{
if(s[i] > s[j]) return 1;
if(s[i] < s[j]) return 2;
}
return 0;
}
if(y1 - x1 > y2 - x2) return 1;
if(y1 - x1 < y2 - x2) return 2;
} int main()
{
int i, j, k;
scanf("%s", s + 1);
n = strlen(s + 1);
for(i = 1; i <= n; i++)
for(j = i; j >= 1; j--)
if(cmp(j, i, d[j - 1], j - 1) == 1)
{
d[i] = j;
break;
}
while(s[d[n] - 1] == '0') d[n]--;
for(i = d[n]; i <= n; i++) f[i] = n;
for(i = d[n] - 1; i >= 1; i--)
{
k = n;
for(j = i; j <= n; j++)
if(cmp(i, j, j + 1, f[j + 1]) == 2)
k = j;
f[i] = k;
}
if(cmp(1, n, d[n], n) == 0)
{
printf("%s", s + 1);
return 0;
}
j = 1;
while(j <= n)
{
for(i = j; i <= f[j]; i++)
printf("%c", s[i]);
j = f[j] + 1;
if(j <= n) putchar(',');
}
return 0;
}

  

[luoguP1415] 拆分数列(DP)的更多相关文章

  1. luoguP1415 拆分数列 [dp]

    题目描述 给出一列数字,需要你添加任意多个逗号将其拆成若干个严格递增的数.如果有多组解,则输出使得最后一个数最小的同时,字典序最大的解(即先要满足最后一个数最小:如果有多组解,则使得第一个数尽量大:如 ...

  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. 基于Vmware player的Windows 10 IoT core + RaspberryPi2安装部署

    本文记录了基于Vmware Player安装Windows10和VS2015开发平台的过程,以及如何在RaspberryPi2.0上启动Windows10 IoT core系统,并通过一个简单的hel ...

  2. cocoapods学习

    1.安装 http://stackoverflow.com/questions/16459028/rvm-install-error-running-requirements-osx-port-ins ...

  3. ipsec配置strongswan.conf和ipsec.conf

    配置strongswan.conf vi /usr/local/etc/strongswan.conf # strongswan.conf - strongSwan configuration fil ...

  4. UVA821 PageHopping (Floyd)

    求所有点直接的平均最短距离,保存一下出现过的点,题目保证是所有点连通,Floyd求出最短路以后两个for统计一下. #include<bits/stdc++.h> using namesp ...

  5. UVA 12563 Jin Ge jin Qu [h] ao 劲歌金曲 (01背包)

    每首只能唱一次,而且中间不能不唱歌,所以先把状态赋值为-1,以区别合法状态和非法状态,在唱歌曲目最多的条件下,离开时间应该尽量晚. 状态定义f[i][j]考虑前i首歌唱歌时间为j的最大唱歌曲目 #in ...

  6. select *from where 和select *from jion on 语句的差别

    https://zhidao.baidu.com/question/541791438.html select 学号 a,成绩 a,姓名 b from 成绩表 a,学生表 b where a.学号=b ...

  7. ObjectiveC中的赋值,对象拷贝,浅拷贝与深拷贝

    在开发过程中我们经常会遇到对象拷贝的问题,下面我们分别讨论赋值操作.对象拷贝.以及浅拷贝(Shallow copy)与深拷贝(Deep copy)的区别与各自的实现方式. 一.不同对象的赋值操作 Ob ...

  8. java并发编程:Executor、Executors、ExecutorService

    1.Executor和ExecutorService Executor:一个接口,其定义了一个接收Runnable对象的方法executor,其方法签名为executor(Runnable comma ...

  9. 屏蔽系统的Ctrl+c/x/v操作

    实现效果: 知识运用: KeyEventArgs类的Control, public bool Control {get;} //获取一个值 该值指示是否曾按下Ctrl键 KeyCode和Handled ...

  10. input提示文字;placeholder字体修改

    在很多网站上我们都看到input输入框显示提示文字,让我们一起来看看如果在input输入框中显示提示文字.我们只需要在<input>标签里添加:placeholder="提示文字 ...