玲珑oj 1121 思维

1121 - Reverse the lights

Time Limit:2s Memory Limit:256MByte

Submissions:376Solved:111

DESCRIPTION

n

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

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

INPUT
输入有两行,第一行包含两个正整数n(1n10000)k(0k1000)

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

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