zoukankan      html  css  js  c++  java
  • 洛谷P1410 子序列 题解 动态规划

    题目链接:https://www.luogu.com.cn/problem/P1410

    题目大意:
    给定一个长度为N(N为偶数)的序列,问能否将其划分为两个长度为N/2的严格递增子序列。

    解题思路:

    定义 (f_{i,j}) 表示前 (i) 个数,(a_i) 所在的子序列长度为 (j) 的情况下,另外一个子序列的最后一个元素的最小值。

    初始时 (f_{1,1} = 0),其他状态设为 (inf)

    最终只需要判断 (f_{n,n/2}) 是否为 (inf) 即可。

    状态转移方程:

    if (a[i-1] < a[i]) f[i][j] = min(f[i][j], f[i-1][j-1]);
    if (f[i-1][i-j] < a[i]) f[i][j] = min(f[i][j], a[i-1]);
    

    示例代码:

    #include <bits/stdc++.h>
    using namespace std;
    const int maxn = 2002;
    int n, a[maxn], f[maxn][maxn];
    int main() {
        while (~scanf("%d", &n)) {
            for (int i = 1; i <= n; i ++) scanf("%d", a+i);
            memset(f, 0x3f, sizeof(f));
            f[1][1] = 0;
            for (int i = 2; i <= n; i ++) {
                for (int j = 1; j <= i && j <= n/2; j ++) {
                    if (a[i-1] < a[i]) f[i][j] = min(f[i][j], f[i-1][j-1]);
                    if (f[i-1][i-j] < a[i]) f[i][j] = min(f[i][j], a[i-1]);
                }
            }
            puts( f[n][n/2] == 0x3f3f3f3f ? "No!" : "Yes!" );
        }
        return 0;
    }
    
  • 相关阅读:
    2019春第八周作业
    2019春第七周作业
    第六周作业
    币值转换
    打印沙漏
    秋季学期学习总结
    人生影响最大的三位老师
    自我介绍
    2018秋季学习总结
    自己
  • 原文地址:https://www.cnblogs.com/quanjun/p/13522998.html
Copyright © 2011-2022 走看看