您的位置:首页 > 其它

HDU 5303 dp

2015-07-24 16:40 369 查看
一个环上有n个苹果树,每个树上有ai个苹果,你有一个容量为k的篮子,装满苹果后要回到起点清空篮子,问你从起点出发,摘完所有苹果所走的最短路程。

苹果最多有100000个

使用两个DP数组,dp[0][i]表示顺时针取i个苹果的最短路程,dp[1][i]表示逆时针取i个苹果的最短路程

ans=Min(dp[0][i],dp[1][sum-i]);

#include "stdio.h"
#include "string.h"
#include "algorithm"
using namespace std;
const __int64 inf=0x3f3f3f3f3f3f;
__int64 dp[2][100010],l,k;
int n,sum;
struct node
{
__int64 x,y;
}a[100010];

bool cmp(node a,node b)
{
return a.x<b.x;
}

__int64 Min(__int64 a,__int64 b)
{
if (a<b) return a;
else return b;
}

void DP()
{
int last,i,j;
memset(dp,0,sizeof(dp));
sum=1;
for (i=0;i<n;i++)
for (j=1;j<=a[i].y;j++)
{
if (sum>k) last=sum-k;else last=0;
dp[0][sum]=dp[0][last]+Min(2*a[i].x,l);
sum++;
}
sum=1;
for (i=n-1;i>=0;i--)
for (j=1;j<=a[i].y;j++)
{
if (sum>k) last=sum-k;else last=0;
dp[1][sum]=dp[1][last]+Min(2*(l-a[i].x),l);
sum++;
}
}

int main()
{
__int64 ans;
int t,i,cnt;
scanf("%d",&t);
while (t--)
{
scanf("%I64d%d%I64d",&l,&n,&k);
cnt=0;
for (i=0;i<n;i++)
{
scanf("%I64d%I64d",&a[i].x,&a[i].y);
cnt+=a[i].y;
}
sort(a,a+n,cmp);
DP();
ans=inf;
for (i=0;i<=cnt;i++)
ans=Min(ans,dp[0][i]+dp[1][cnt-i]);
printf("%I64d\n",ans);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: