hdu5303 Delicious Apples

对这个环,有3种操作:

1.顺时针过去取

2.逆时针过去取

3.绕这个环一圈取

1和2如果走过了环的一半,就变成了3,所以1和2是不能走过环的一半的。

而对于1和2,每次取的k个苹果,其花费的距离必然为max(xi)*2|i=1,2...k,所以拿的这k个苹果的距离一定是当前这半环中的最大的k个,因为既然花费距离已定,那不如将这次操作的优化价值提升到最大,也就是每次都尽量消去距离最远的苹果。

对于3,同样,花费一定是L,每次也同样要消去距离最远的苹果。但是,可以发现,如果操作中出现了2次操作3,那么这个操作一定不是最优的,因为可以通过1和2两次操作取得两次操作3获得的苹果,且花费更低。所以操作中只可能出现一次操作3且这次操作3若要发生,一定发生在操作刚开始,因为此时进行操作3的优化价值是最大的。

那么只需要枚举是否发生了操作3及这次操作3取得了哪些苹果即可。

#include
   
   
    
    
#include
    
    
     
     
#include
     
     
      
      
#include
      
      
       
       
using namespace std;
typedef long long ll;
int lr[100010],rr[100010];
int lri,rri;
ll dpl[100010],dpr[100010];
int n,K;ll L;
ll cl(){
    int i,j,k;
    int ai,ak;
    scanf("%I64d %d %d",&L,&n,&K);
    lri=rri=0;
    for(i=0;i
       
       
         =L){ for(;ai;rr[++rri]=L-ak,--ai); } else{ for(;ai;lr[++lri]=ak,--ai); } } sort(lr+1,lr+lri+1); sort(rr+1,rr+rri+1); dpr[0]=dpl[0]=0; for(i=1;i<=K&&i<=lri;++i) dpl[i]=2*lr[i]; for(i=1;i<=K&&i<=rri;++i) dpr[i]=2*rr[i]; for(i=K+1;i<=lri;++i) dpl[i]=dpl[i-K]+2*lr[i]; for(i=K+1;i<=rri;++i) dpr[i]=dpr[i-K]+2*rr[i]; if(lri+rri<=K) return min(L,dpl[lri]+dpr[rri]); ll s=dpl[lri]+dpr[rri]; for(i=lri-1;i>=0&&i>lri-K;--i){ s=min(s,L+dpl[i]+dpr[max(0,rri-(K-(lri-i)))]); } return s; }; int main(){ #ifndef ONLINE_JUDGE freopen("in.txt","r",stdin); freopen("out.txt","w",stdout); #endif int t;scanf("%d",&t); while(t--) printf("%I64d\n",cl()); return 0; }; 
       
      
      
     
     
    
    
   
   

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值