hdu5303Delicious Apples dp

//在一个长度为L的环上有n棵苹果树,
//第i棵苹果树在位置顺时针距离0点为xi,其上有苹果ai
//问从0点开始,一个篮子最多装k个苹果,问最需要走
//多少路程能够摘完所有苹果
//可以知道最多绕圆走一次
//dp[0][i] 表示从左边开始取i个苹果的最小代价
//dp[1][i] 表示从右边开始取i个苹果的最小代价
//可以枚举左边开始取多少个,得到最小代价
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std ;
const int maxn = 1e5+10 ;
typedef long long ll ;
const ll inf = 1e19 ;
pair<int,int> a[maxn] ;
ll dp[2][maxn] ;
int main()
{
    int t ;
    scanf("%d" , &t) ;
    while(t--)
    {
        int l , n , k ;
        scanf("%d%d%d" , &l , &n , &k) ;
        for(int i = 1;i <= n;i++){
           int x , y;
           scanf("%d%d"  ,&x , &y) ;
           a[i] = make_pair(x,y) ;
        }
        sort(a+1, a+1+n) ;
        int len = 0 ;
        dp[0][0] = dp[1][0] = 0 ;
        for(int i = 1;i <= n;i++){
            int tmp = a[i].second ;
            while(tmp--){
                dp[0][++len] = (len-k>0?dp[0][len-k]:0)+a[i].first;
            }
        }
        len = 0 ;
        for(int i = n;i > 0;i--){
            int tmp = a[i].second;
            while(tmp--){
                dp[1][++len] =  (len-k>0?dp[1][len-k]:0)+l-a[i].first ;
            }
        }
        ll ans = inf ;
        for(int i = 0;i <= len;i++){
            ans = min(ans,min((dp[0][i]+dp[1][len-i])*2,(dp[0][i]+(len-i-k>0?dp[1][len-i-k]:0))*2+l)) ;
        }
        printf("%lld\n" , ans) ;
    }
    return 0 ;
}

你可能感兴趣的:(hdu5303Delicious Apples dp)