zoukankan      html  css  js  c++  java
  • Luogu 1415-拆分数列-动态规划

    Solution

    首先要找到使得最后一个数最小, 只需定义一个数组$pre[i]$ 从区间$[pre[i], i]$表示的数, 是最小的能使前面的数递增的方案。

    $[ pre[n], n]$即为最小的最后一个数。

    接着我们依据这找出的最后一个数, 向前dp, 找出使得每个数都最大的方案。

    前导0是非常坑的

    我觉得我也不怎么懂这道dp, 看得有点懵TAT

    Code

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<algorithm>
     4 #define rd read()
     5 #define rep(i,a,b) for(int i = (a); i <= (b); ++i)
     6 #define per(i,a,b) for(int i = (a); i >= (b); --i)
     7 using namespace std;
     8 
     9 const int N = 505;
    10 
    11 int pre[N], nxt[N], a[N], n;
    12 int ans[N];
    13 
    14 char s[N];
    15 
    16 bool cmp(int l1, int r1, int l2, int r2) {
    17     while(a[l1] == 0 && l1 <= r1) l1++;
    18     while(a[l2] == 0 && l2 <= r2) l2++;
    19     if(r1 < l1 || r2 < l2) return 0;
    20     if(r1 - l1 < r2 - l2) return 1;
    21     else if(r1 - l1 > r2 - l2) return 0;
    22     for(int i = 0; i <= r2 - l2; ++i) 
    23         if(a[l1 + i] > a[l2 + i]) return 0;
    24         else if(a[l1 + i] < a[l2 + i]) return 1;
    25     return 0;
    26 }
    27 
    28 int main()
    29 {
    30     scanf("%s", s + 1);
    31     n = strlen(s + 1);
    32     for(int i = 1; i <= n; ++i) a[i] = s[i] - '0';
    33     for(int i = 1; i <= n; ++i) pre[i] = 1;
    34     for(int i = 2; i <= n; ++i)
    35         for(int j = i; j >= 1; --j)
    36             if(cmp(pre[j - 1], j - 1, j, i)) {
    37                 pre[i] = j; break;
    38             }
    39     nxt[pre[n]] = n;
    40     for(int i = pre[n]; i <= n; ++i) nxt[i] = n;
    41     int pos0 = pre[n];
    42     while(a[pos0 - 1] == 0) pos0--, nxt[pos0] = n;
    43     for(int i = pre[n] - 1; i; --i)
    44         for(int j = pre[n] - 1; j >= i; --j)
    45             if(cmp(i, j, j + 1, nxt[j + 1])) {
    46                 nxt[i] = j; break;
    47             }
    48     for(int l = 1, i = nxt[1]; l <= n; i = nxt[l]) {
    49         for(int j = l; j <= i; j++) printf("%d",a[j]);
    50         l = i + 1;
    51         if(l > n) break;
    52         printf(",");
    53     }
    54     putchar('
    ');
    55 }
    View Code
  • 相关阅读:
    浅谈均值、方差、标准差、协方差的概念及意义
    数据库设计的基本步骤
    VS添加lib库
    Android activity_main.xml删除边缘距离,充满屏幕
    Android 设置旋转朝向
    WebStorm注册码
    VS禁止特定警告
    VS 高亮显示不带后缀的C++头文件
    VS2010设置C++包含目录和库目录
    读取STL模型
  • 原文地址:https://www.cnblogs.com/cychester/p/9580754.html
Copyright © 2011-2022 走看看