玲珑oj 1121 思维

时间:2022-03-17 21:04:29
1121 - Reverse the lights

Time Limit:2s Memory Limit:256MByte

Submissions:376Solved:111

DESCRIPTION

有n

个灯,初始时都是不亮的状态,每次你可以选择一个某一个灯,不妨记为x,所有满足和x距离不超过k的灯的状态都将被翻转,选择第i个灯的代价记为ci

,问最终所有灯都是亮的状态的最小花费.

INPUT
输入有两行,第一行包含两个正整数n(1≤n≤10000)和k(0≤k≤1000)

第二行包含n个整数,分别表示ci(0≤ci≤109)

 
OUTPUT
输出一行表示答案
SAMPLE INPUT
3 1 1 1 1
SAMPLE OUTPUT
1
一开始思路还是对的,可惜一直想怎么dp,最后发现不需要dp,直接扫描一次求最优解就好了。
每个灯最多只开一次,多开也没用,开了又关相当于没起到作用,我们只要依次枚举第一个开的地点,他所达到的范围内的灯就都不用开了,
直接跳到最近的一个处于关闭状态的灯前开启这个灯即可。
如果我们不这么做的话,那么两盏开启的灯之间就会出现重叠部分而抵消,为了处理这些重叠我们需要再开一些灯这样又会出现更多的重叠。
具体的证明,我也没证出来,但是感觉一下确实是这样子的。
 #include<bits/stdc++.h>
using namespace std;
int main()
{
int n,k,i,j;
long long ans=1e18,c[];
cin>>n>>k;
for(i=;i<=n;++i) cin>>c[i];
if(!k) {ans=;for(i=;i<=n;++i)ans+=c[i];n=-; }
for(i=;i<=n;++i)
{
int s=i,e=n-k,x=s;
long long p=;
if(s-k>) break;
for(j=s;j<=n;j+=(*k)+) {
p+=c[j];
x=j;
}
if(x+k>=n) {ans=min(ans,p);}
}
cout<<ans<<endl;
return ;
}