uva 1379(dp)

来源:互联网 发布:article标签有利于seo 编辑:程序博客网 时间:2024/05/05 07:42

题意:有n个人要和m个敌人打比赛,要打g场比赛,每天最多打一场,持续g+10天,然后给出n个人中每个人打敌人的胜率,且一个人打了比赛后需要休息4天,然后给出第i天要打的敌人序号,0表示不打,问最多能得多少分(胜率累加和)。
题解:dp的思路比较好想,f[i][x][j][k][l]表示在第i天,第i-1天是第x个人打的,第i-2天是第j个人打的,第i-3天是第k个人打的,第i-4天是第l个人打的情况下最大得分,先把打每个敌人胜率从大到小排序,然后每次只取前5个人(休息四天,要和之前的人比对是否是同一人)。
状态转移方程:
如果第i天要打比赛:
f[i][x][j][k][l] = max(f[i][x][j][k][l],f[i - 1][j][k][l][o] + p[g[i]][x])
不打:
f[i][0][j][k][l] = max(f[0][x][j][k][l],f[i - 1][j][k][l][o])

#include <cstdio>#include <cstring>#include <algorithm>using namespace std;const int N = 105;struct Point {    int v, id;}p[N][N];int n, m, d, g[N * 3], res;int f[2][10][10][10][10];bool cmp(Point a, Point b) {    return a.v > b.v;}int judge(int x, int y) {    if (x == 0 || y == 0)        return 0;    return p[x][y].id;}int main() {    int t;    scanf("%d", &t);    while (t--) {        scanf("%d%d%d", &n, &m, &d);        for (int i = 1; i <= m; i++) {            for (int j = 1; j <= n; j++) {                scanf("%d", &p[i][j].v);                p[i][j].id = j;            }            sort(p[i] + 1, p[i] + 1 + n, cmp);        }        res = 0;        d += 10;        for (int i = 1; i <= d; i++)            scanf("%d", &g[i]);        memset(f[0], 0, sizeof(f[0]));        for (int i = 1; i <= d; i++) {            int now = i % 2;            int pre = 1 - now;            memset(f[now], 0, sizeof(f[now]));            if (g[i]) {                for (int x = 1; x <= 5; x++) {                    for (int j = 0; j <= 5; j++) {                        if (i > 1 && judge(g[i], x) == judge(g[i - 1], j))                            continue;                        for (int k = 0; k <= 5; k++) {                            if (i > 2 && judge(g[i], x) == judge(g[i - 2], k))                                continue;                            for (int l = 0; l <= 5; l++) {                                if (i > 3 && judge(g[i], x) == judge(g[i - 3], l))                                    continue;                                for (int o = 0; o <= 5; o++) {                                    if (i > 4 && judge(g[i], x) == judge(g[i - 4], o))                                        continue;                                    f[now][x][j][k][l] = max(f[now][x][j][k][l], f[pre][j][k][l][o] + p[g[i]][x].v);                                    res = max(res, f[now][x][j][k][l]);                                }                            }                        }                    }                }            }            else {                for (int j = 0; j <= 5; j++)                    for (int k = 0; k <= 5; k++)                        for (int l = 0; l <= 5; l++)                            for (int o = 0; o <= 5; o++) {                                f[now][0][j][k][l] = max(f[now][0][j][k][l], f[pre][j][k][l][o]);                                res = max(res, f[now][0][j][k][l]);                            }            }        }        printf("%.2lf\n", res * 1.0 / 100);    }    return 0;}
0 0