HDU 5303

来源:互联网 发布:华东大数据交易所 编辑:程序博客网 时间:2024/06/05 04:55

HDU 5303
题意是在一个圆上,有n颗苹果树,相对起点的顺时针距离为xi,每棵树上有ai个苹果。现在带上一个容量为K的篮子,从起点出发,问将所有苹果收回来至少要花多少时间?
Apple
显然,从起点出发,不论从从左或是右,在不跨过终点m时,摘到K个苹果后最佳的路径是原路返回。跨过了中点m,那么最佳路径是走一圈回到起点。显然,我们至多只会跨过m一次,因为跨过中点是不得已为之,走一圈是最长路径。
那么摘苹果就分成了三种情况,顺时针不过m采摘,逆时针不过m采摘,跨m采摘(至多一次)。预处理出单侧不跨m采摘的花费。
ldp记录采摘起点到顺时针的第i个苹果所需要的花费,那么
ldp[i]=ldp[i-K]+lcost[i]。
rdp记录采摘起点到逆时针的第i个苹果所需要的花费,那么
rdp[i]=rdp[i-K]+rcost[i]。
我们再枚举,跨越m的那次采摘的采摘区间,那么显然我们要让这次采摘覆盖单侧采摘中花费最大的那些苹果,即离起点最远的那些苹果。
假设这次采摘,在左侧摘i个,那么右侧摘K-i个,
total_cost就由(ldp[lmax]+rdp[rmax])*2变成了(ldp[lmax-i]+rdp[rmax-(K-i)])*2+L。枚举过程中取最小值即可。

//#include<bits/stdc++.h>#pragma comment(linker, "/STACK:1024000000,1024000000")#include<cstdio>#include<cstring>#include<queue>#include<vector>#include<algorithm>#define LS (root<<1)#define RS ((root<<1)|1)#define LSON LS,l,mid#define RSON RS,(mid+1),r#define MID mid=((l+r)/2)#define LL long long#define mm(a,b) memset(a,b,sizeof(a))using namespace std;const int maxn=3e4+5;const LL Inf=1e18;vector<LL> ldp, rdp;int main(){    int T, n;    int L, K;    int a, b;    scanf("%d",&T);    while(T--){        ldp.clear();        rdp.clear();        ldp.push_back(0);        rdp.push_back(0);        scanf("%d%d%d",&L, &n, &K);        for(int i=0;i<n;i++){            scanf("%d%d",&a, &b);            while(b--){                if(2*a<L) ldp.push_back(a);                else rdp.push_back(L-a);            }        }        sort(ldp.begin(),ldp.end());        sort(rdp.begin(),rdp.end());        for(int i=K;i<ldp.size();i++) ldp[i]+=ldp[i-K];//把摘到i-K为止的cost累加到i上过        for(int i=K;i<rdp.size();i++) rdp[i]+=rdp[i-K];        LL ans=(ldp[(int)ldp.size()-1]+rdp[(int)rdp.size()-1])*2;        for(int i=0;i<=K;i++){            a=max(0,(int)ldp.size()-1-i);            b=max(0,(int)rdp.size()-1-(K-i));            LL tmp=(ldp[a]+rdp[b])*2;            ans=min(ans,L+tmp);        }        printf("%lld\n",ans);    }    return 0;}
0 0
原创粉丝点击