HDU 3757 dp

来源:互联网 发布:西蒙智力量表软件 编辑:程序博客网 时间:2024/04/30 11:02
#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]);

0 0