P3112-[USACO14DEC]后卫马克Guard Mark【贪心】
正題
題目鏈接:https://www.luogu.org/problemnew/show/P3112
題目大意
有nnn只牛,每只牛有hi,wi,sih_i,w_i,s_ihi?,wi?,si?分別表示有多高,有多重,上面最多承載總共多重的牛。
選擇一些牛依次擺放要求高度超過TTT且上面還能增加最重的物品。
解題思路
首先我們考慮已經(jīng)選定了牛了,然后如何擺放是最優(yōu)的:
resti=si?∑j=i+1nwjrest_i=s_i-\sum_{j=i+1}^nw_jresti?=si??j=i+1∑n?wj?
我們考慮是否交換兩項
resti=si?(∑j=i+1nwj)rest_i=s_i-(\sum_{j=i+1}^nw_j)resti?=si??(j=i+1∑n?wj?)
resti+1=si+1?(∑j=i+1nwj)?wirest_{i+1}=s_{i+1}-(\sum_{j=i+1}^nw_j)-w_iresti+1?=si+1??(j=i+1∑n?wj?)?wi?
考慮是否交換要求
max{min{resti,resti+1},min{Nresti,Nresti+1}}max\{min\{rest_i,rest_{i+1}\},min\{Nrest_i,Nrest_{i+1}\}\}max{min{resti?,resti+1?},min{Nresti?,Nresti+1?}}
兩邊同時加上(∑j=i+1nwj)(\sum_{j=i+1}^nw_j)(∑j=i+1n?wj?)
那么就是求
max{min{si,si+1?wi},min{si+1,si?wi+1}}max\{min\{s_i,s_{i+1}-w_i\},min\{s_{i+1},s_{i}-w_{i+1}\}\}max{min{si?,si+1??wi?},min{si+1?,si??wi+1?}}
然后si>si?+wi?1s_i>s_{i}-+w_{i-1}si?>si??+wi?1?且si+1>si+1?wis_{i+1}>s_{i+1}-w_isi+1?>si+1??wi?(顯而易見)
如果si+1?wi≤si?wi?1s_{i+1}-w_i\leq s_i-w_{i-1}si+1??wi?≤si??wi?1?
那么有si+1?wi≤sis_{i+1}-w_i\leq s_isi+1??wi?≤si?那么交換肯定更優(yōu)
那么只要si+wis_i+w_isi?+wi?從大到小選擇就好了。
codecodecode
#include<cstdio> #include<algorithm> #include<cstring> #define ll long long using namespace std; const ll N=21; ll n,T,sh,maxs,ans,w,MS; struct node{ll h,w,s; }a[N]; bool cmp(node x,node y) {return x.s+x.w>y.s+y.w;} int main() {scanf("%lld%lld",&n,&T);for(ll i=1;i<=n;i++)scanf("%lld%lld%lld",&a[i].h,&a[i].w,&a[i].s);sort(a+1,a+1+n,cmp);MS=1<<n;ans=-1;for(ll i=0;i<MS;i++){sh=w=0;maxs=2147483647;for(ll j=n;j>=1;j--)if((i>>j-1)&1){sh+=a[j].h;maxs=min(maxs,a[j].s-w);w+=a[j].w;}if(sh<T) continue;ans=max( maxs,ans);}if(ans<0)printf("Mark is too tall");else printf("%lld",ans); }總結(jié)
以上是生活随笔為你收集整理的P3112-[USACO14DEC]后卫马克Guard Mark【贪心】的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: P3514-[POI2011]LIZ-L
- 下一篇: 无线路由器怎么连接手机热点上网呀tpli