1. 程式人生 > >玲瓏oj 1121 思維

玲瓏oj 1121 思維

開始 ram ++i 兩個 atom amp -m bit -c

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 }

玲瓏oj 1121 思維