“玲珑杯”线上赛 Round #15 河南专场:A -- Reverse the lights

来源:互联网 发布:数控机床编程技术 编辑:程序博客网 时间:2024/05/19 06:35


A -- Reverse the lights

Time Limit:2s Memory Limit:256MByte

Submissions:277Solved:83

DESCRIPTION

nn个灯,初始时都是不亮的状态,每次你可以选择一个某一个灯,不妨记为xx,所有满足和xx距离不超过kk的灯的状态都将被翻转,选择第ii个灯的代价记为cici,问最终所有灯都是亮的状态的最小花费.

INPUT
输入有两行,第一行包含两个正整数n(1n10000)k(0k1000)n(1≤n≤10000)和k(0≤k≤1000)第二行包含nn个整数,分别表示ci(0ci109)ci(0≤ci≤109)
OUTPUT
输出一行表示答案
SAMPLE INPUT
3 1
1 1 1
SAMPLE OUTPUT
1
大佬思路:

第一题实际上还是个dp,我们会发现如果对第i位进行操作 结果把之前的开着的又关住的话那么这次操作没有任何意义(因为相当于返回到了之前某个已经开了一定的从开头开始算的连续的几个灯的状态),所以,如果想对i这个位置进行操作的前提是从i-k到第i位都是关着的灯,因此我们可以发现对于dp[i]=dp[i-k-k-1]+num[i]然后直接往后递推就行了。

大佬图解:


AC代码:

#include<iostream>#include<stdio.h>#include<string.h>using namespace std;const int maxn = 1e4+10;const long long inf = 1e13;long long dp[maxn];long long cost[maxn];int n,k;long long Min(long long a,long long b){    if(a<b) return a;    else return b;}int main(){    while(~scanf("%d%d",&n,&k))    {        for(int i = 1; i <= n; i++)            scanf("%lld",&cost[i]);        fill(dp,dp+maxn,inf);          long long ans = inf;        ///1...k,k+1,打开里面任意一盏灯,其左侧灯会全亮        for(int i = 1; i <= k+1; i++)        {            if(i>n) break;            dp[i] = cost[i];  ///开第i栈灯花费为i            /**开第i栈灯,其左侧灯会全亮,其右侧所能波及的范围大于等于n,            则打开第i栈灯就可以使所有灯都亮起来,这种情况下,答案是满足该            条件灯中,开灯花费最小的值**/            if(i+k>=n)                ans = Min(ans,cost[i]);        }        for(int i = 2*k+2; i <= n; i++)        {            dp[i] = dp[i-2*k-1]+cost[i];            if(i+k>=n)                ans = Min(ans,dp[i]);        }        printf("%lld\n",ans);    }    return 0;}


阅读全文
0 0