My Brute
题目链接:Click Here~
题目分析:
有两个人进行游戏对决,就是跟拳王游戏一样的。游戏规则是每个人都有N个游戏人物,以及每个人物有有其自己的伤害值和血量。而每个游戏者获胜又都会相应的获得一些分数。现在已经给出了两个人的各自N个游戏人物的出场顺序,要求你用最少的交换次数来获得最大的分数值。
思路分析:
跟HDU Assignment一样的。都是对原来的值进行扩展以保证优先选原来的点。别的就不说了,因为思路跟那题一样的。但是用那题的建图方法一直TEL。。。。无解。
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#define MAXN 100
#define MAX 1010
#define INF 100000000
int W[MAXN][MAXN],N,slack;
int V[MAXN],H[MAXN],P[MAXN],A[MAXN],B[MAXN];
int Lx[MAXN],Ly[MAXN],Link[MAXN];
bool S[MAXN],T[MAXN];
int Win(int i,int j)
{
if((H[i]-1) / B[j] >= (P[j]-1)/A[i])
return V[i];
else
return -V[i];
}
inline int Read()
{
char ch = getchar();
while(!isdigit(ch)) ch = getchar();
int sum = 0;
while(isdigit(ch)){
sum *= 10;
sum += ch - '0';
ch = getchar();
}
return sum;
}
void Init()
{
int i,j;
memset(W,0,sizeof(W));
for(i = 1;i <= N;++i)
V[i] = Read();
for(i = 1;i <= N;++i)
H[i]= Read();
for(i = 1;i <= N;++i)
P[i]= Read();
for(i = 1;i <= N;++i)
A[i]= Read();
for(i = 1;i <= N;++i)
B[i]= Read();
for(i = 1;i <= N;++i){
for(j = 1;j <= N;++j){
W[i][j] = 10 * (Win(i,j) + MAX);
if(i == j)
W[i][j] += 1;
}
}
}
int Match(int i)
{
int j,tmp;
S[i] = 1;
for(j = 1;j <= N;++j)if(!T[j]){
tmp = Lx[i] + Ly[j] - W[i][j];
if(tmp==0){
T[j] = 1;
if(Link[j]==-1||Match(Link[j])){
Link[j] = i;
return 1;
}
}
else if(tmp < slack)
slack = tmp;
}
return 0;
}
int EK()
{
int i,j;
for(i = 1;i <= N;++i){
Link[i] = -1;
Lx[i] = Ly[i] = 0;
for(j = 1;j <= N;++j)
if(Lx[i] < W[i][j])
Lx[i] = W[i][j];
}
for(i = 1;i <= N;++i){
for(;;){
memset(S,0,sizeof(S));
memset(T,0,sizeof(T));
slack = INF;
if(Match(i))
break;
// if(slack == INF)
// return 0;
//update
for(j = 1;j <= N;++j){
if(S[j])
Lx[j] -= slack;
if(T[j])
Ly[j] += slack;
}
}
}
return 1;
}
//int Get()
//{
// int i,sum = 0;
// for(i = 1;i <= N;++i){
// if(Link[i]!=-1)
// sum += W[Link[i]][i];
// }
// return sum;
//}
void printresult()
{
int i, res = 0, num = 0;
for(i = 1; i <= N; i ++)
{
if(W[Link[i]][i] % 10 != 0)
num ++;
res += W[Link[i]][i] / 10 - MAX;
}
if(res > 0)
printf("%d %.3f%%\n", res, 100.0 * num / N);
else
printf("Oh, I lose my dear seaco!\n");
}
int main()
{
// freopen("Input.txt","r",stdin);
while(scanf("%d",&N),N)
{
Init();
EK();
printresult();
// int sum = Get();
// if(sum >= 0){
//
// double rati = sum%MAXN*1.0/N;
// printf("%d %.3lf%%\n",sum/MAXN,rati*100.0);
// }
// else
// puts("Oh, I lose my dear seaco!");
}
return 0;
}