zoukankan      html  css  js  c++  java
  • hdu 5303 DP(离散化,环形)+贪心

    题目无法正常粘贴,地址:http://acm.hdu.edu.cn/showproblem.php?pid=5303

    大意是给出一个环形公路,和它的长度,给出若干颗果树的位置以及树上的果子个数。

    起点为0,背包大小为K,求最小走多少距离能摘完所有的果子并回到起点。

    观察得知,公路长度L虽然上界10^9,但果子总和最多10^5,还是可做的。

    显然如果想回家时在左半边肯定逆时针返回更近,在右边同理顺时针更近。

    所有取果子的操作无非三种情况(顺时针出发逆时针返回&&逆时针出发顺时针返回&&顺时针一次走一圈<==>逆时针走一圈)。

    *走整圈的情况==>最起码在装完左边的果子之后背包还有富余,不然没有往右走的必要,*而且在整个取果子过程中至多转一圈,否则只会比ans大。

    由于背包的大小限制每次取果子的个数,为了方便处理数据,*我们不妨将果子做离散化处理,存进x数组中(x[i]即第i个果子的位置);

    我们可以将左/右两边的果子按距离远点的距离排序放入两个l/r容器中。

    之后dp1[i]表示从原点顺时针出发取得第i个果子再返回原点所需时间的一半(*保存为一半的距离方便计算),dp2同理.

    处理完之后假设不饶圈,ans=dp1[l.size()]+dp2[r.size()];

    接着我们枚举绕一圈的拿到的果子数即可,[0,K],而且不能超出左边的果子数,所以[0,min(K,l.size())];

    对于此时,左边已经捡走了l.size()-i的果子到起点,右边就是r.size-(K-i),考虑到可能背包剩余空间大于右边的剩余果子,将其与0取较大者即可。

    思考过程略复杂但代码量不多,值得多思考思考,精巧之处*号标注。

    DP方程dp[i]={                  //i从1开始

                        l[i]                i<=k;

                        l[i]+dp[i-k]    i>k; 

    }

    如果第i个果子大于k显然他要走到第i个果子的位置再返回,从路上带走k个果子,如果路上还有则继续返回带走,

    在这个过程中如果想要路程最短化,根据贪心,他应该优先带走[1,i]中靠近处的果子,这样再次返回时走的更短。

    #include<bits/stdc++.h>
    #include
    <algorithm> using namespace std; #define LL long long LL x[100005]; LL dp1[100005],dp2[100005]; vector<LL> l,r; int main() { int N,M,K,L,T; int i,j; LL X,A; scanf("%d",&T); while(T--){int cnt=0; LL ans; l.clear(); r.clear(); scanf("%d %d %d",&L,&N,&K); for(i=0;i<N;++i){ scanf("%lld%lld",&X,&A); for(j=1;j<=A;++j) x[++cnt]=(LL)X; } for(i=1;i<=cnt;++i){ if(2*x[i]<L) l.push_back(x[i]); else r.push_back(L-x[i]); }int szl=l.size(),szr=r.size(); sort(l.begin(),l.end()); sort(r.begin(),r.end()); for(i=0;i<szl;++i){ dp1[i+1]=(i+1<=K?l[i]:dp1[i+1-K]+l[i]); } for(i=0;i<szr;++i){ dp2[i+1]=(i+1<=K?r[i]:dp2[i + 1-K]+r[i]); } ans=(dp1[szl]+dp2[szr])*2; for(i=1;i<=szl&&i<=K;++i){ int p1=szl-i; int p2=max(0,szr-(K-i)); ans=min(ans,2*(dp1[p1]+dp2[p2])+L); } printf("%lld ",ans); } return 0; }
  • 相关阅读:
    生成日期列表的函数.sql
    Archlinux下启用Thinkpad功能键
    使用临时表进行编号重排的处理示例.sql
    行值动态变化的交叉报表处理示例.sql
    工作日处理函数(标准节假日).sql
    字符串在编号查询中的应用示例及常见问题.sql
    分段更新函数.sql
    TypeMembersToIL.cs
    排序规则在拼音处理中的应用.sql
    text与image字段转换处理示例.sql
  • 原文地址:https://www.cnblogs.com/zzqc/p/6942053.html
Copyright © 2011-2022 走看看