HZOJ Blue
Blue:
貪心。
我們不妨給蛤定一個(gè)先后順序,則貪心策略即從右至左每只蛤依次往最遠(yuǎn)的石子跳。
證明:
如果最右的蛤不往最遠(yuǎn)的石子跳,而是選擇了一個(gè)較近的石子,那么必然會(huì)存在一個(gè)該蛤左邊的蛤越過了它跳向其右邊。因?yàn)槊總€(gè)蛤的能力是相同的,我們可以交換路線使得該貪心策略不變差。
接著用歸納法可以證明對于所有蛤該策略最優(yōu)。
復(fù)雜度O(?N )
各種大佬用各種方法A了這道題……ooo的sb線段樹,什么set,隊(duì)列啥的都用上了……貌似只有我和b哥打了網(wǎng)絡(luò)流,(B神蓋世)比我厲害用了線段樹優(yōu)化建邊+網(wǎng)絡(luò)流,復(fù)雜度什么都好像都說的過去,而我只是沖著那30分去的。
網(wǎng)絡(luò)流就比較好想了,建立兩個(gè)超級源點(diǎn)S,SS,S向SS連容量為m的邊,將每個(gè)石頭拆開,連容量為1的邊(如果每個(gè)石頭可以跳k次那網(wǎng)絡(luò)流板e(cuò)rb正解),然后相距不超過d的石頭連邊,最大流就是答案,不過復(fù)雜度好像說不過去……
正解:
將所有的蛤(不是青蛙嗎???)看作一個(gè)整體,那么每次跳都會(huì)占據(jù)一段石頭,這樣是最優(yōu)的,而且每次青蛙都會(huì)盡量向遠(yuǎn)處跳,所以我么可以得到這樣一個(gè)結(jié)論:若一只蛤在i,下次跳最遠(yuǎn)能到j(luò),那么最多會(huì)剩下j-i+1只蛤(即把之間全占滿),這樣取符合條件最大值就是了。可以用單調(diào)指針實(shí)現(xiàn)。
1 #include<iostream> 2 #include<cstdio> 3 #define LL long long 4 #define ma(x) memset(x,0,sizeof(x)) 5 using namespace std; 6 int T,n,m,d,l,a[1000010]; 7 signed main() 8 { 9 cin>>T; 10 while(T--) 11 { 12 cin>>n>>m>>d>>l; 13 for(int i=1;i<=n;i++)cin>>a[i]; 14 if(d==l){puts("Excited");continue;} 15 int ans=m;a[n+1]=l; 16 int R=0;bool pd=0; 17 for(int i=0;i<=n+1;i++) 18 { 19 while(a[R+1]-a[i]<=d&&R<n+1)R++; 20 if(R==n+1)break; 21 ans=min(ans,R-i); 22 } 23 if(ans==m)puts("Excited"); 24 else cout<<ans<<endl; 25 } 26 } 和Dinic比起來短好多……?
轉(zhuǎn)載于:https://www.cnblogs.com/Al-Ca/p/11331094.html
總結(jié)
- 上一篇: IE7不能显示PNG
- 下一篇: 改造我们的学习:有钱不会花,抱着金库抓瞎