Hdu5303 Delicious Apples 貪心
阿新 • • 發佈:2017-05-22
int ios namespace font define continue sort pri rac
題目鏈接:
HDU5303
題意:
有一條環形的長為L的路,倉庫在位置0處,
這條路上有n棵蘋果樹,給出每棵蘋果樹的位置和蘋果數量,
問用 一次最多能裝K個蘋果的籃子 把這條路上全部蘋果採回倉庫最少須要走的距離
解題思路:
這條路是環形的,先把果樹分為兩部分,圓的左半邊算一部分,圓的右半邊算還有一部分
對全部蘋果依據距離排序 , 用類似背包的思想, 統計左半邊,右半邊用 來回走(來回的長度一定小於一個圓環的周長)的方式採集完蘋果所須要走的最少距離;
最後 考慮須要走一圈的情況:左邊 多出k1( <K)個蘋果,右邊多出k2 (<k) 個蘋果.
推斷 來回拿k1所需走的距離+來回拿k2所需走的距離 和 圓周長L 的 大小關系就可以得出對應答案
代碼:
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #define LL long long #define maxn 100050 using namespace std; int dis[maxn],cnt; int ldis[maxn],rdis[maxn]; int cnt1,cnt2; LL lsum[maxn],rsum[maxn]; int cmp(int a,int b) { return a<b; } int main() { // freopen("in.txt","r",stdin); int T,m,n,k,a,b,L; scanf("%d",&T); while(T--) { scanf("%d%d%d",&L,&m,&k); cnt=cnt1=cnt2=0; while(m--) { scanf("%d%d",&a,&b); if(a==0) continue; if((a<<1)<=L) for(int i=1;i<=b;i++) ldis[++cnt1]=a; else for(int i=1;i<=b;i++) rdis[++cnt2]=L-a; } sort(ldis+1,ldis+cnt1+1,cmp); sort(rdis+1,rdis+cnt2+1,cmp); cnt=cnt1+cnt2; for(int i=1;i<=cnt1;i++) //左半邊 通過來回的方式拿完 if(i<=k) lsum[i]=ldis[i]; else lsum[i]=ldis[i]+lsum[i-k]; for(int i=1;i<=cnt2;i++) //右半邊....... if(i<=k) rsum[i]=rdis[i]; else rsum[i]=rdis[i]+rsum[i-k]; LL ans=(lsum[cnt1]+rsum[cnt2])<<1; k=min(k,cnt); int l_,r_; for(int i=1;i<=cnt1&&i<=k;i++) //枚舉走一圈時,左半邊拿的蘋果數量 { l_=cnt1-i,r_=max(0,cnt2-k+i); ans=min(ans,L+((lsum[l_]+rsum[r_])<<1)); } printf("%I64d\n",ans); } return 0; }
Hdu5303 Delicious Apples 貪心