zoukankan      html  css  js  c++  java
  • G

    https://codeforces.com/problemset/problem/1077/F1

    这个其实是一个比较简单的dp了

    题目大意:

    给你n个数,让你从n个数里选出x个数,并且每隔k个至少选一个数。

    开始不知道怎么去写,也不知道怎么去定义dp

    这个应该是对于dp不是特别的熟练,实际上dp用途很广,而且可以用到的地方很多,效果也很好。

    这种时候就应该大胆一点,你需要什么,想达成什么效果那就去这样定义。

    这个题目,我们希望dp可以帮我们解决前面n个数,选了x个数的最大和,而且这个还必须每隔k就选择了一个数。

    这个是大问题,子问题是什么呢?

    如果我们选第i个数,那么前面n-1个数,选了x-1个数的最大和。。。。

    否则就是我们不选第i个数,那么前面n-1个数,选了x个数的最大和。  ----这种情况我们最多可以向前面推k-1次

    所以我们要怎么定义呢?

    首先要有一维来记录到第几个数了,还有一维就是要记录我们选了多少个了,

    两维记录可以唯一确定每一个状态,所以两维就够了

    那到底怎么去定义这个dp呢?dp的含义是什么呢?

    这个我觉得不是很好想。

    dp[i][j]表示前面i个数,已经选了j个数的最大和吗?

    但是因为这个有区间限制,就是每隔k就必须有一个数,所以这个时候我们就要确定前面的那个值的位置,

    所以我们就定义为已经选择了第i个数,前面i个数 选了j个数的最大和。

    状态定义好了之后,就是转移方程的确定了。

    dp[i][j]=max(dp[i][j],dp[s][j-1]+a[i])

    这个s其实就是i往前推,然后去最大值,所以需要三维。

    而且这个往前推最多推k个数。

    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <queue>
    #include <algorithm>
    #include <vector>
    #include <iostream>
    #define inf 0x3f3f3f3f3f3f3f3f
    using namespace std;
    const int maxn = 1010;
    typedef long long ll;
    ll dp[2 * maxn][2 * maxn];
    ll a[maxn];
    
    int main()
    {
        int n, k, x;
        scanf("%d%d%d", &n, &k, &x);
        for (int i = 1; i <= n; i++) scanf("%lld", &a[i]);
        for(int i=0;i<=n;i++)
        {
            for(int j=0;j<=x;j++)
            {
                dp[i][j] = -inf;
            }
        }
        dp[0][0] = 0;
        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=x;j++)
            {
                for(int h=1;h<=k&&h<=i;h++)
                {
                    if (dp[i - h][j - 1] == -inf) continue;
                    dp[i][j] = max(dp[i][j], dp[i - h][j - 1] + a[i]);
                //    printf("dp[%d][%d]=%lld
    ", i, j, dp[i][j]);
                }
            }
        }
        ll ans = -inf;
        for (int i = n - k + 1; i <= n; i++) ans = max(ans, dp[i][x]);
        if (ans < 0) printf("-1
    ");
        else printf("%lld
    ", ans);
        return 0;
    }
    线性dp
  • 相关阅读:
    UDP
    TCP
    python基础之socket编程
    单列模式
    元类
    issubclass()和isinstance()
    手持机设备公司(WINCE/ANDROID/LINUX)
    Android Hal 分析
    Android JNI 使用的数据结构JNINativeMethod详解
    MTK GPIO 一些理解
  • 原文地址:https://www.cnblogs.com/EchoZQN/p/10945175.html
Copyright © 2011-2022 走看看