基於貪心的區間覆蓋問題
阿新 • • 發佈:2018-11-08
cf 某div2 某題 很像區間覆蓋 但實則十分不同 它不是線段覆蓋 而是點覆蓋
資料小可以用暴力標記一個數組但我感覺從中沒啥意思(然而實則是懶得看暴力的程式碼
so 貼一下程式碼 很巧妙的從後貪心
#include <bits/stdc++.h> using namespace std; int a[1005]; int main() { int n,r; cin>>n>>r; for(int i =0;i<n;i++) cin>>a[i]; int ans=0; for(int i=1;i<=n;i++) { int cnt=0; for(int j=min(i+r-1,n);j>=1&&j>=i-r+1;j--) { if(a[j]==1) { ans++; cnt++; i=j+r-1; break; } } if(cnt==0) { cout<<-1; return 0; } } cout<<ans; }
Besides 附加一下線段覆蓋的貪心的程式碼,
ps .mark這個部落格https://blog.csdn.net/chenguolinblog/article/details/7882316
&https://blog.csdn.net/Dear_Jia/article/details/76548987
//此種演算法貌似不適用於散點覆蓋 適合線段覆蓋 #include<cstdio> #include<algorithm> #include<bits/stdc++.h> using namespace std; const int maxn = 1000+10; int N, T,r,acount=0; struct Interval { int start, end; }a[maxn]; bool cmp(const Interval &a, const Interval &b) { if(a.start < b.start) return true; else if(a.start == b.start && a.end < b.end) return true; else return false; } void solve() { sort(a, a+acount, cmp); /*cout<<acount<<endl; for(int w=0;w<acount;w++) { cout<<a[w].start<<" "<<a[w].end<<endl; }*/ int count = 0; int s, e = 1; int index = 0; int ok = 1; while(e <T) { s = e;//更新覆蓋區域 for(int i=index; i<acount; i++) { if(a[i].start <= s) { if(a[i].end >= s)e=max(a[i].end,e);//取符合條件的最遠區間。 } else { index = i;//不符合條件則需要換區間 break; } } if(s >= e) { ok = 0; break; } else { count++; // cout<<count<<endl; } } //cout<<count<<endl; if(ok) printf("%d\n", count); else printf("-1\n"); } int main() { scanf("%d%d",&N,&r); T=N; int D; int j=0; for(int i=0; i<N; i++) { scanf("%d",&D); if(D==1) { acount++; a[j].start=max(i-r+1,1); a[j].end=min(i+r,T); j++; } } solve(); return 0; }