您的位置:首页 > 其它

hdu4924 Football Manager

2015-10-26 21:24 232 查看
这题上来我是没有思路的。因为目标值关涉到的因素太多而直接枚举的复杂度又太高。

目标值由两部分合成,一部分是队员的CA和与PA和,另一部分是队员之间的relationship。

前者是简单的代数累加,而后者显然才是本题需要解决的问题。

由于relatioship由具体的出场方案所决定,因此不知道哪些队员上场就不可能知道它的值是多少,并且估算它有用的上下界也是困难的。

因此只能想到枚举,首先枚举哪些队员上场(这一步的复杂度就非常高,如果按题目给的数据范围对于强数据是根本不可能通过的)。

于是第二部分的值就确定了,现在只需要解决第一部分的求值。

这一部分不需要暴力枚举(如果仍然枚举仅在此处最坏情况下复杂度也会上万),因为既然是代数和的累加必然可以找到不同状态之间的联系。

对于某个特定的队员只会被任命在4个位置中的一个,现在方案只会是内部队员出场位置的调整。那么我们可以想到dp,通过枚举-更新的方法寻求最佳方案。

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <map>
#include <string>
#include <vector>
#include <set>
#include <cmath>
#include <ctime>
#pragma comment(linker, "/STACK:102400000,102400000")
#define lson (u << 1)
#define rson (u << 1 | 1)
#define rep(i, a, b) for(i = a; i < b; i++)
#define repi(i, a, b, c) for(i = a; i < b; i += c)
#define cls(i, j) memset(i, j, sizeof i);
using namespace std;
typedef long long ll;
const double eps = 1e-6;
const double pi = acos(-1.0);
const int maxn = 100 + 10;
const int maxm = 1050;
const int inf = 0x3f3f3f3f;
const ll linf = 0x3fffffffffffffff;
const ll mid = 1e9 + 7;

struct P{
int id, o[4];
int c[4], p[4], cmax;
bool operator < (const P &rhs) const{
return cmax > rhs.cmax;
}
}a[maxn];

int n, m;
int idx[maxn];
int g[maxn][maxn];

int f(char ch){
switch(ch){
case 'G' : return 0;
case 'D' : return 1;
case 'M' : return 2;
case 'S' : return 3;
}
}

int select[20];
int l[20];

struct Point{
int x, y;
Point(int x = 0, int y = 0) : x(x), y(y) {}
bool operator < (const Point &rhs){
return x < rhs.x || x == rhs.x && y < rhs.y;
}
Point operator + (const Point &rhs){
return Point(x + rhs.x, y + rhs.y);
}
bool operator == (const Point &rhs){
return x == rhs.x && y == rhs.y;
}
}dp[15][15][15][15];//i, 0, 1, 2

Point ANS, INF = Point{-inf, -inf};

Point max(Point lhs, Point rhs) { return lhs < rhs ? rhs : lhs; }

void update(int u, int kind, int n0, int n1, int n2){
Point dest = dp[u][n0][n1][n2] + Point{a[select[u]].c[kind], a[select[u]].p[kind]};
Point *src = &dp[u + 1][n0 + (0 == kind)][n1 + (1 == kind)][n2 + (2 == kind)];
(*src) = max((*src), dest);
}

void cal(){
int cnt[4];
cls(cnt, 0);
int i, j, k, u, v;
rep(i, 0, 11) rep(j, 0, 4) if(a[select[i]].o[j]) ++cnt[j];
rep(i, 0, 4) if(cnt[i] < l[i]) return;
int ca = 0;
rep(i, 0, 11) rep(j, i, 11){
int x = a[select[i]].id, y = a[select[j]].id;
ca += g[x][y];
if(i != j) ca += g[y][x];
}
int high = ca;
rep(i, 0, 11) high += a[select[i]].cmax;
if(high < ANS.x) return;//curcial pruning
rep(i, 0, 12) rep(j, 0, cnt[0] + 1)
rep(k, 0, cnt[1] + 1) rep(u, 0, cnt[2] + 1) dp[i][j][k][u] = INF;
dp[0][0][0][0] = Point{0, 0};
rep(i, 0, 11) rep(j, 0, l[0] + 1) rep(k, 0, l[1] + 1) rep(u, 0, l[2] + 1){
if(dp[i][j][k][u] == INF) continue;
rep(v, 0, 4) if(a[select[i]].o[v]) update(i, v, j, k, u);
}
ANS = max(ANS, Point(ca, 0) + dp[11][l[0]][l[1]][l[2]]);
}

void fswap(int x, int y){
int i;
rep(i, 0, n) swap(a[i].c[x], a[i].c[y]), swap(a[i].p[x], a[i].p[y]), swap(a[i].o[x], a[i].o[y]);
swap(l[x], l[y]);
}

void dfs(int pos, int num){
//num::how many palyers has been chosen
if(num == 11){
cal();
return;
}
if(pos == n || n - pos + num < 11) return;
select[num] = pos;
dfs(pos + 1, num + 1);
dfs(pos + 1, num);
}

void solve(){
ANS = INF;
dfs(0, 0);
if(ANS == INF) puts("Poor Manager!");
else printf("%d %d\n", ANS.x, ANS.y);
}

int main(){
//freopen("in.txt", "r", stdin);
int T;
scanf("%d", &T);
char buf[10];
while(T--){
scanf("%d", &n);
int i, j, tem;
rep(i, 0, n) rep(j, 0, 4) a[i].o[j] = 0;
rep(i, 0, n){
a[i].cmax = -inf;
scanf("%d%d", &a[i].id, &tem);
rep(j, 0, tem){
scanf("%s", buf);
int tem1 = f(buf[0]);
a[i].o[tem1] = 1;
scanf("%d%d", &a[i].c[tem1], &a[i].p[tem1]);
a[i].cmax = max(a[i].cmax, a[i].c[tem1]);
}
}
cls(g, 0);
sort(a, a + n);
scanf("%d", &m);
rep(i, 0, m){
int u, v, w;
scanf("%d%d%s%d", &u, &v, buf, &w);
g[u][v] = (buf[0] == 'D' ? -1 : 1) * w;
}
scanf("%d-%d-%d", &l[1], &l[2], &l[3]);
l[0] = 11 - l[1] - l[2] - l[3];
int maxp = 3, maxv = l[3];
rep(i, 0, 3) if(l[i] > maxv) maxv = l[i], maxp = i;
if(maxp != 3) fswap(3, maxp);
solve();
}
return 0;
}


View Code
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: