HDU 5303 Delicious Apples(DP + 贪心)

来源:互联网 发布:湖北航天信息开票软件 编辑:程序博客网 时间:2024/05/02 01:49

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5303


题意:有一个长度为L的环,环上有N棵苹果树,有个每次能装K个苹果的篮子,装满后要回到搬到起点,问从起点出发,最少需要多少距离将所有苹果搬到起点


思路:dp[0][i]代表顺时针出发摘掉i个苹果回到起点的最短距离,dp[1][i]相应表示逆时针

从贪心角度考虑,我们每次肯定按照距离顺序拿掉这K个苹果,对于顺逆时针,每次返回起点时都需要考虑是走环还是走半圈进行转移


#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>#include <vector>#include <utility>#include <cmath>#include <queue>#include <set>#include <map>#include <climits>#include <functional>#include <deque>#include <ctime>#define lson l, mid, rt << 1#define rson mid + 1, r, rt << 1 | 1#pragma comment(linker, "/STACK:102400000,102400000")using namespace std;typedef long long ll;const int maxn = 100100;struct node{    int x, v;    bool operator < (const node & rhs) const    {        return x < rhs.x;    }} a[maxn];ll sum, dp[2][maxn];int n, k, l;int main(){    int t;    cin >> t;    while (t--)    {        sum = 0;        memset(dp, -1, sizeof(dp));        cin >> l >> n >> k;        for (int i = 0; i < n; i++)        {            scanf("%d%d", &a[i].x, &a[i].v);            sum += a[i].v;        }        sort(a, a + n);        dp[0][0] = dp[1][0] = 0;        ll cnt = 1, p;        for (int i = 0; i < n; i++)            for (int j = 0; j < a[i].v; j++)            {                p = cnt - k > 0 ? cnt - k : 0;                if (dp[0][p] == -1) continue;                dp[0][cnt] = dp[0][p] + min(2 * a[i].x, l);                cnt++;            }        cnt = 1;        for (int i = n - 1; i >= 0; i--)            for (int j = 0; j < a[i].v; j++)            {                p = cnt - k > 0 ? cnt - k : 0;                if (dp[1][p] == -1) continue;                dp[1][cnt] = dp[1][p] + min(2 * l - 2 * a[i].x, l);                cnt++;            }        long long ans = 1e16;        for (int i = 0; i <= sum; i++)            ans = min(ans, dp[0][i] + dp[1][sum - i]);        cout << ans << endl;    }    return 0;}


0 0
原创粉丝点击