洛谷-----普及試煉場-----貪心 p1094紀念品分組 P1803 凌亂的yyy / 線段覆蓋
阿新 • • 發佈:2018-12-23
P1803 凌亂的yyy / 線段覆蓋
對於每個開始時間,只能選擇參加一次比賽或者不參加比賽,因此只考慮對於一個開始時間結束最早的比賽。設d(i)為i時間及其之後開始的最多參加的比賽數,則若i時間沒有開始的比賽,d(i)=d(i+1),否則d(i)=max(d(i+1),d(i開始的結束時間)+1)。
#include<iostream> #include<cstring> using namespace std; int n,a[1000005],d[1000005]; int main() { memset(a,-1,sizeof(a)); int x,y; cin>>n; for(int i=1;i<=n;i++) { cin>>x>>y; if(a[x]<0 || a[x]>y)a[x]=y; } d[1000000]=0; for(int i=1000000-1;i>=0;i--) { if(a[i]<0)d[i]=d[i+1]; else { d[i]=max(d[i+1],d[a[i]]+1); } } cout<<d[0]<<endl; return 0; }
p1094紀念品分組
從大到小,依次買完價格為i的,對於價格i的,儘量帶上價格<=w-i的一起買。注意有一個坑。
#include<iostream> using namespace std; int w,n,cnt[205],ans; int main() { freopen("input.in","r",stdin); int x; cin>>w>>n; while(n--){cin>>x;cnt[x]++;} for(int i=w;i>0;i--) { for(int j=0;cnt[i]&&w-i-j>0;j++) { while(cnt[i]&&cnt[w-i-j]) { ans++; cnt[i]--; cnt[w-i-j]--; //注意這裡的細節,i有可能==w-i-j,這樣的話有可能cnt[i] 為-1,特殊處理。 if(cnt[i]==-1) { cnt[i]++; for(int k=i-1;k>0;k--)if(cnt[k]) { cnt[k]--; break; } } } } if(cnt[i]) { ans+=cnt[i]; cnt[i]=0; } } cout<<ans<<endl; return 0; }