[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]$为数列 ...
随机推荐
- mount_cd9660:/dev/acd0: Input/output error
mount -t cd9660 /dev/acd0 /cdrom g_vfs_done():acd0[READ(offset32768, length=204]error =5 mount_cd966 ...
- 利用js日期控件重构WEB功能
开发需求:网页中的日期部门(注册页面和查询条件)都用js日期控件重写 页面一:更新员工页面 empUpdate.jsp 中增加 onfocus 事件 入职日期:<input id="h ...
- jmeter中登录和提交收银出现的错误
登录出现的错误 登录界面如图所示: 为了防止登录跳转的问题response code 302的问题,要设置 2.提交收银界面 当系统设置必须传送jison格式时,要在HTTP Header Manag ...
- Android学习总结(十四) ———— ListView Item多布局的实现
一.基本概念 实现一个Item的多布局.像我们经常在用的各种即时通讯工具,QQ.微信等,假设他们的会话界面是ListView实现的,那么ListView就有多种Item布局,要实现ListView里面 ...
- NBUT 1115 Cirno's Trick (水)
题意: 给出多个double数,去掉其最小的和最大的,再对余下的求均值. 思路: 再输入时将最大和最小去掉,顺便统计非最值的和,输出时除一下个数即可. #include <bits/stdc++ ...
- iosopendev配置
Permission denied, please try again.Permission denied, please try again.Permission denied (publickey ...
- UVA1663 Purifying Machine (匈牙利算法,二分图最大匹配)
模版集合个数减少是因为匹配串集合中没被匹配过的一对串匹配了.所以就是找一个二分图最大匹配. 因为集合X和Y是不好分开的,但是可以直接跑,两个集合都会跑一遍,所以一个匹配会被算两次,返回的时候除以2就行 ...
- 2018_oakland_linuxmalware
2018年oakland论文:理解linux恶意软件 论文地址:http://www.s3.eurecom.fr/~yanick/publications/2018_oakland_linuxmalw ...
- 动态规划初步-单向STP
一.题目 给一个m行n列(m <= 10,n <= 100)的整数矩阵,从第一列任何位置出发每次往右.右下.右上走一格,最终达到最后一列.要求经过的整数之和最小.整个矩阵是环形的,即第一行 ...
- 浏览器输入一个url到整个页面显示出来经历了哪些过程?
https://cloud.tencent.com/developer/article/1396399 https://www.cnblogs.com/haonanZhang/p/6362233.ht ...