HDU 3757 Evacuation Plan

来源:互联网 发布:xml格式转json数组 编辑:程序博客网 时间:2024/05/15 20:19

        dp。由于内存限制非常严格,所以要用滚动数组,而且本来输出location的时候我也是用的二维int数组,然后就超内存了,只好改成了bool类型了。对于每个队,要么是和前一个队去同一个地方,要么去前一个队的后一个地方,只有这样才能保证最后总花费最小,这也算是贪心了一下吧,然后就很容得出状态转移方程了:

        dp[i][j] = min(dp[i - 1][j - 1] + abs(a[i] - b[j]), dp[i - 1][j] + abs(a[i] - b[j]));a数组表示队位置,b数组表示工地位置,dp[i][j]表示第i只队去第j个工地(可以想出,每一个i都是可以确定一个j的范围的,因为如果i的位置太靠前,那么后面的队伍就不够用了所以m-j<=n-i,然后最远是i,因为比i大的话前面的就不够用了)。

         对于第二问,我们只需标记一下第i个队取第j个工地的最小值的时候,i-1哪个队去的j还是j-1就好了,true表示j。

#include<functional>#include<algorithm>#include<iostream>#include<cstring>#include<cstdio>#include<cmath>#include<vector>#include<queue>#include<map>#include<set>#define REP(i, n) for(int i=0; i<n; i++)#define CLR(a, b) memset(a, b, sizeof(a))#define LL long longusing namespace std;const int N = 4040;const LL INF = 1e18;struct Node{    int val, id;    bool operator < (const Node& rhs) const    {        return val < rhs.val;    }}a[N], b[N];LL dp[2][N];int ans[N];bool pt[N][N];int main(){    int n, m, t;    scanf("%d", &t);    while(t --)    {        scanf("%d", &n);        REP(i, n) scanf("%d", &a[i].val), a[i].id = i;        scanf("%d", &m);        REP(i, m) scanf("%d", &b[i].val), b[i].id = i;        sort(a, a + n);        sort(b, b + m);        for(int i = 0; i < m; i ++) dp[0][i] = INF;        dp[0][0] = abs(a[0].val - b[0].val);        pt[0][0] = true;        int now = 1;        for(int i = 1; i < n; i ++)        {            REP(j, m) dp[now][j] = INF;            //for(int j = 0; j < m; j ++)            for(int j = m + i - n; j <= min(i, m - 1); j ++)            {                LL tmp = dp[now^1][j] + abs(a[i].val - b[j].val);                if(tmp < dp[now][j])                {                    dp[now][j] = tmp;                    pt[i][j] = true;                }                if(!j) continue;                tmp = dp[now^1][j - 1] + abs(a[i].val - b[j].val);                if(tmp < dp[now][j])                {                    dp[now][j] = tmp;                    pt[i][j] = false;                }            }            now ^= 1;        }        printf("%I64d\n", dp[now^1][m - 1]);        ans[a[n - 1].id] = b[m - 1].id;        int tmp = pt[n - 1][m - 1] ? m - 1 : m - 2;        for(int i = n - 2; i >= 0; i --)        {            ans[a[i].id] = b[tmp].id;            tmp = pt[i][tmp] ? tmp : tmp - 1;        }        REP(i, n)            printf("%d%c", ans[i] + 1, i == n - 1 ? '\n' : ' ');    }    return 0;}


原创粉丝点击