AcWing 3499- 序列最大收益 - 线性DP

Posted Chivas_/Regal

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了AcWing 3499- 序列最大收益 - 线性DP相关的知识,希望对你有一定的参考价值。

题目:
在这里插入图片描述
思路:
是一个决策某个位置删不删的问题,所以DP可解
我第一反应是区间DP,但是我们需要一维去记录删掉多少个元素
所以我们用一维表示枚举的位数,一维表示删除多少个元素
就变成了一道线性DP

发现这个几乎可以用LIS问题的方法写,相比较于LIS问题
少了个大小的限制,但多了个对删除多少个元素的限制
同时把 a [ i ] a[i] a[i]接到 a [ j ] a[j] a[j]后面的收益从 1 1 1变成了 w [ a [ i ] ] [ a [ j ] ] w[a[i]][a[j]] w[a[i]][a[j]]
数据量200,明显是让我们加一重循环去维护第二维的

所以问题就转化成了一个带一点变动的LIS问题

代码:

const int N = 210;
int w[N][N], a[N];
int dp[N][N];//dp[i][j]表示到第i位删去了j个元素后的最优解
int n, k, m;
int res;

int main(){
    read(n); read(k); read(m);
    for(int i = 1; i <= m; i ++) read(a[i]);
    for(int i = 1; i <= n; i ++) for(int j = 1; j <= n; j ++) read(w[i][j]);
    
    for(int i = 1; i <= m; i ++){			//推到了第几位
        for(int j = 0; j <= k; j ++){		//枚举到第i位删去多少个
            for(int o = 1; o < i; o ++){	//枚举第i位以前的o位,并代表 (i, o) 的元素是我们跳过的
                if(j >= i - o - 1)			//检查一下第i位要删去的这j个元素够不够跳跃 (i, o) 这么多个元素
                 	//第i位删了 o 个,所以第o个位置的状态是删去 j-(i-o+1) 个,拼到后面得到w[a[o]][a[i]]
                    dp[i][j] = MAX(dp[i][j], dp[o][j - (i - o - 1)] + w[a[o]][a[i]]),
                    res = MAX(dp[i][j], res);//维护最大值
            }
        }
    }write(dp[m][k]);
}

以上是关于AcWing 3499- 序列最大收益 - 线性DP的主要内容,如果未能解决你的问题,请参考以下文章

3499. 序列最大收益

2021夏季每日一题 week1 未完结

最大收益问题 线性规划网络流

最大收益问题 线性规划网络流

AcWing 895 最长上升子序列 - (线性DP) or (贪心+二分优化)

AcWing 314. 低买 (线性DP)打卡