码迷,mamicode.com
首页 > 其他好文 > 详细

洛谷P1415 拆分数列

时间:2017-10-12 21:40:23      阅读:196      评论:0      收藏:0      [点我收藏+]

标签:==   输入输出   names   string   需要   bool   clu   name   col   

题目背景

【为了响应党中央勤节俭、反铺张的精神,题目背景描述故事部分略去^-^】

题目描述

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

输入输出格式

输入格式:

 

共一行,为初始的数字。

 

输出格式:

 

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

 

输入输出样例

输入样例#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 拆分数列

标签:==   输入输出   names   string   需要   bool   clu   name   col   

原文地址:http://www.cnblogs.com/luoyibujue/p/7657955.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!