[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))
这样从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)的更多相关文章
- luoguP1415 拆分数列 [dp]
题目描述 给出一列数字,需要你添加任意多个逗号将其拆成若干个严格递增的数.如果有多组解,则输出使得最后一个数最小的同时,字典序最大的解(即先要满足最后一个数最小:如果有多组解,则使得第一个数尽量大:如 ...
- P1415 拆分数列 DP
传送门: 题意: 将一个数字串分成许多不同的小串,使得这些小串代表的数字严格递增,要求最后一个数字尽可能地小. 然后满足字典序尽可能大. 思路: 由于最后一个数字要尽可能地小,所以先处理出每个数的L[ ...
- 洛谷P1415 拆分数列[序列DP 状态 打印]
题目背景 [为了响应党中央勤节俭.反铺张的精神,题目背景描述故事部分略去^-^] 题目描述 给出一列数字,需要你添加任意多个逗号将其拆成若干个严格递增的数.如果有多组解,则输出使得最后一个数最小的同时 ...
- 洛谷 P1415 拆分数列 解题报告
拆分数列 题目背景 [为了响应党中央勤节俭.反铺张的精神,题目背景描述故事部分略去^-^] 题目描述 给出一列数字,需要你添加任意多个逗号将其拆成若干个严格递增的数. 如果有多组解,则输出使得最后一个 ...
- 洛谷P1415 拆分数列(dp)
题目链接:传送门 题目: 题目背景 [为了响应党中央勤节俭.反铺张的精神,题目背景描述故事部分略去^-^] 题目描述 给出一列数字,需要你添加任意多个逗号将其拆成若干个严格递增的数.如果有多组解,则输 ...
- 洛谷P1415 拆分数列
题目背景 [为了响应党中央勤节俭.反铺张的精神,题目背景描述故事部分略去^-^] 题目描述 给出一列数字,需要你添加任意多个逗号将其拆成若干个严格递增的数.如果有多组解,则输出使得最后一个数最小的同时 ...
- 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 ...
- BZOJ2431:[HAOI2009]逆序对数列(DP,差分)
Description 对于一个数列{ai},如果有i<j且ai>aj,那么我们称ai与aj为一对逆序对数.若对于任意一个由1~n自然数组成的 数列,可以很容易求出有多少个逆序对数.那么逆 ...
- P1415 拆分数列
传送门 DP数列长度过大无法枚举,考虑DP设f1[i]储存以第i个字符为结尾时,的最后一个数最小时,这个数的开头的位置(很难想有木有)OK,状态有了,方程想一想就出来了:设$num[i][j]$为数列 ...
随机推荐
- Actionbar Demo
源码下载:http://download.csdn.net/detail/bx276626237/8874119
- 在Ubuntu16.04安装YouCompleteMe
作为从事了4年多嵌入式Linux工作的软件工程师,最近决定完全在ubuntu上工作,使用vim进行代码的阅读和编辑,然后尝试去安装vim相关的各种插件.从来没用过代码补全的我,在网上找到了插件omni ...
- java里面byte数组和String字符串怎么转换
//string 转 byte[] String str = "Hello"; byte[] srtbyte = str.getBytes(); // byte[] 转 strin ...
- Hibernate 中批量处理数据
一.批量处理操作 批量处理数据是指在一个事务场景中处理大量数据.在应用程序中难以避免进行批量操作,Hibernate提供了以下方式进行批量处理数据: (1)使用HQL进行批量操作 数据库层面 ...
- java 一个对象多少大,占用多少内存
1.instrumentation这种方法还是靠谱的 一个对象占用多少字节? 2.sizeof库 <!-- https://mvnrepository.com/artifact/com.carr ...
- 20171201Jsp Jstl详细配置
Jsp Jstl详细配置 1. 下载包 http://archive.apache.org/dist/jakarta/taglibs/standard/binaries/jakarta-taglibs ...
- Python学习笔记3(字典)
创建字典 dict函数 字典的格式化字符串 字典方法 clear copy fromkeys 序列是一个按照一定顺序将值进行组织的数据结构形式,可以通过索引对其进行征引.另外还有一种数据结构是通过名字 ...
- 文件读写FILE类
1. 新建一个文件: FILE *f = fopen("a.txt","w+"); (1)fopen()函数介绍fopen的原型是:FILE *fopen(co ...
- 【git】自动换行转换autocrlf
#####windows git config --global core.autocrlf true #####linux git config --global core.autocrlf inp ...
- docker apache安装
文章来源: 1.添加镜像 # docker pull httpd2. 2.创建httpd文件 # mkdir /data/httpd2. 3.启动apache # docker run -it -p ...