关禁闭(dp)

26 篇文章 0 订阅
26 篇文章 0 订阅

题目:https://ac.nowcoder.com/acm/contest/62642/B

妈妈成功将小竹救了出来,她觉得小竹实在是太笨了,决定关小竹一周禁闭。可是小竹哪里能忍受失去自由,他早就偷藏了一部手机用于联系你,请求你帮助他逃离。

你通过观察发现他房间内有 n 个可用于制成绳子的物品,第 i 个的长度为 ai​ 。当你使用第 i个物品制作绳子时,其右侧的 k 个物品(不含第 i 个物品)就无法再被用于制作绳子 。最终,小竹用选择的物品制成绳子,绳子的长度是所选择物品的长度之和。

小竹想知道,他能制作的绳子长度最长为多少?

输入描述:

第一行两个整数 n,k(1≤k≤n≤2000)
第二行n个用空格隔开的整数,第i个整数为 ai(1≤ai≤2000)表示第i个物品的长度。

输出描述:

一行一个整数,表示绳子的最长长度。

示例1

输入

1 2 3 4 5

输出

7

说明

使用第2个和第5个物品制成绳子

总结:

经典的dp思维:状态转移方程 -- 该题两种状态的储存

第1种就是新位置的储存

第2中就是老位置的储存

具体代码:

 dp[a] = max( dp[y]+q[a], dp[a-1] );          //选择最大长度进行储存

代码献上(dp):

#include<bits/stdc++.h>

using namespace std;

int n, k;
const int N = 2023;

int q[N];

int dp[N];                                              //数组的每一个位置表示从头到该位置最大长度

int main()
{
    ios::sync_with_stdio(false);   
    cin.tie(0), cout.tie(0);

    cin >> n >> k;

    for (int a = 1; a <= n; a++)cin >> q[a];           //数据输入

    for (int a = 1; a <= n; a++)
    {
        int y = max(0, a - k - 1);                    //跳过k个物品

        dp[a] = max( dp[y]+q[a], dp[a-1] );          //选择最大长度进行储存

        //dp[a-1]              表示上一个储存最大的
        //dp[y]+q[a]           表示该位置的长度与前第k个物品

    }
    cout << dp[n];
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值