码迷,mamicode.com
首页 > 其他好文 > 详细

HDU 3757 dp

时间:2016-05-13 00:51:37      阅读:132      评论:0      收藏:0      [点我收藏+]

标签:

#include <cstdio>
#include <algorithm>
#include <cstring>
#include <iostream>
using namespace std;
const int maxn = 4E3 + 10;
const long long INF = 1LL << 60;
short path[maxn][maxn];
long long f[maxn];
struct Node
{
        long long d;
        int num, sh;
};
int n, m, T, kase;
Node x[maxn], y[maxn];
bool cmpd(const Node &a, const Node &b)
{
        return a.d < b.d;
}
bool cmpnum(const Node &a, const Node &b)
{
        return a.num < b.num;
}
void solve(int i, int j)
{
        if (i != 1) solve(i - 1, path[i][j]);
        x[i].sh = y[j].num;
}
int main(int argc, char const *argv[])
{
        scanf("%d", &T);
        while (T--)
        {
                scanf("%d", &n);
                for (int i = 1; i <= n; i++)
                        scanf("%I64d", &x[i].d), x[i].num = i;
                scanf("%d", &m);
                for (int i = 1; i <= m; i++)
                        scanf("%I64d", &y[i].d), y[i].num = i;
                sort(x + 1, x + 1 + n, cmpd);
                sort(y + 1, y + 1 + m, cmpd);
                for (int i = 0; i <= max(n, m); i++)
                        f[i] = INF;
                f[1] = abs(x[1].d - y[1].d);
                for (int i = 2; i <= n; i++)
                        for (int j = min(i, m); j >= 1; j--)
                        {
                                if (f[j] < f[j - 1])
                                {
                                        f[j] = f[j] + abs(x[i].d - y[j].d);
                                        path[i][j] = j;
                                }
                                else
                                {
                                        f[j] = f[j - 1] + abs(x[i].d - y[j].d);
                                        path[i][j] = j - 1;
                                }
                        }
                printf("%I64d\n", f[m]);
                solve(n, m);
                sort(x + 1, x + 1 + n, cmpnum);
                for (int i = 1; i < n; i++)
                        printf("%d ", x[i].sh);
                printf("%d\n", x[n].sh);
        }
        return 0;
}


分别对人和shelter从小到大排序之后再dp,这样可以消除后效性。
设f[i][j]表示第i个人放在第j个遮蔽物里,则有:f[i][j]=min(f[i-1][j],f[i-1][j-1])+abs(x[i]-y[j]);

HDU 3757 dp

标签:

原文地址:http://blog.csdn.net/tczxw/article/details/51348187

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!