hdu 5303 Delicious Apples(dp)

来源:互联网 发布:iphone自动点击软件 编辑:程序博客网 时间:2024/05/22 12:52

题意:一个长为L的圈种上n颗树,每棵树的坐标为xi,结了ai个苹果,用大小为k的篮子把所有苹果装回来,问最少走多少路

解一:被神奇的dp教做人了

#include <stdio.h>#include <string.h>#include <algorithm>#define ll __int64#define MIN(a,b) ((a)<(b)?(a):(b))const int maxn=100005;using namespace std;ll dp[3][maxn];struct aaa{    int x,a;}tree[maxn];int cmp(aaa a,aaa b){    return a.x<b.x;}int main(){    int t;    int l,n,k;    while(scanf("%d",&t)!=-1)    {        while(t--)        {            scanf("%d%d%d",&l,&n,&k);            for(int i=0;i<n;i++)                scanf("%d%d",&tree[i].x,&tree[i].a);            sort(tree,tree+n,cmp);            dp[0][0]=dp[1][0]=0;            int fr,ed=1;            for(int i=0;i<n;i++)              //顺时针每个苹果取到时走的路            {                for(int j=0;j<tree[i].a;j++)                {                    fr=ed-k>0?ed-k:0;                    dp[0][ed]=dp[0][fr]+(2*tree[i].x>l?l:2*tree[i].x);                    ed++;                }            }            ed=1;            ll sum=0;            for(int i=n-1;i>=0;i--)        //逆时针每个苹果取到时走的路            {                sum+=tree[i].a;                for(int j=0;j<tree[i].a;j++)                {                    fr=ed-k>0?ed-k:0;                    dp[1][ed]=dp[1][fr]+(2*(l-tree[i].x)>l?l:2*(l-tree[i].x));                    ed++;                }            }            ll lenth=1000000000;            for(ll i=0;i<=sum;i++)                lenth=MIN(lenth,dp[0][i]+dp[1][sum-i]);   //找最小的            printf("%I64d\n",lenth);        }    }    return 0;}
解二:神奇的贪心,分成两个半圆,左右分别贪到k一下,最后再贪一圈,不过左右贪心从最远的树开始贪

0 0