uva 1379 - Pitcher Rotation(dp)

来源:互联网 发布:应用中心源码 编辑:程序博客网 时间:2024/05/17 22:29

题目链接:uva 1379 - Pitcher Rotation


题目大意:给出n,表示由n个人组成的战队,接着是m,表示有m个敌人,g表示要比赛的天数,给出g后,比赛的天数起始是g+10,然后是一个m*n的矩阵,g[i][j]表示第j个敌人被i打败后,战队所得到的分数。然后g+10个数,表示每天需要挑战的敌人是谁,0代表说休息;每个人出战的次数没有限制,但是比过一场后要休息4天,问说战队的最高得分。


解题思路:注意题目中的一点,说每个人比完一场赛后要休息4天,那么也就是说对于每个敌人来说,被派去和他打的人就只可能是得分比较高的5个。所以只用开dp[i][a][b][c][d]表示第i天时,第i-1天为a,i-2为b,i-3为c,i-4为d(这里的a,b,c,d表示说那天所对应敌人的前5个较大得分的序号)然后转移到dp[i+1][x][a][b][c],x所对应的序号要和a,b,c,d对应的人的序号不同。


#include <cstdio>#include <cstring>#include <algorithm>using namespace std;const int N = 105;const int M = 10;struct state {int val, u;}g[N][N];int n, m, d, t[N*3];int dp[2][M][M][M][M];inline bool cmp (const state& a, const state& b) {return a.val > b.val;}inline int cat (int j, int i) {if (j == 0 || i == 0)return 0;return g[i][j].u;}void init () {scanf("%d%d%d", &n, &m, &d);for (int i = 1; i <= m; i++) {for (int j = 1; j <= n; j++) {scanf("%d", &g[i][j].val);g[i][j].u = j;}sort(g[i]+1, g[i] + n + 1, cmp);}d += 10;for (int i = 1; i <= d; i++)scanf("%d", &t[i]);}double solve () {memset(dp[0], 0, sizeof(dp[0]));for (int i = 1; i <= d; i++) {int now = i%2;int pre = 1-now;memset(dp[now], 0, sizeof(dp[now]));if (t[i]) {for (int j = 1; j <= 5; j++) {for (int x = 0; x <= 5; x++) {if (i > 1 && cat(j, t[i]) == cat(x, t[i-1])) continue;for (int y = 0; y <= 5; y++) {if (i > 2 && cat(j, t[i]) == cat(y, t[i-2])) continue;for (int z = 0; z <= 5; z++) {if (i > 3 && cat(j, t[i]) == cat(z, t[i-3])) continue;for (int a = 0; a <= 5; a++) {if (i > 4 && cat(j, t[i]) == cat(a, t[i-4])) continue;dp[now][j][x][y][z] = max(dp[now][j][x][y][z], dp[pre][x][y][z][a] + g[t[i]][j].val);}}}}}} else {for (int x = 0; x <= 5; x++) {for (int y = 0; y <= 5; y++) {for (int z = 0; z <= 5; z++) {for (int a = 0; a <= 5; a++) {dp[now][0][x][y][z] = max(dp[now][0][x][y][z], dp[pre][x][y][z][a]);}}}}}}int ans = 0;int u = d%1;for (int x = 0; x <= 5; x++)for (int y = 0; y <= 5; y++)for (int z = 0; z <= 5; z++)for (int a = 0; a <= 5; a++)ans = max(ans, dp[u][x][y][z][a]);return ans / 100.0;}int main () {int cas;scanf("%d", &cas);while (cas--) {init ();printf("%.2lf\n", solve());}return 0;}


1 0
原创粉丝点击