Problem C
Time Limit : 3000/800ms (Java/Other) Memory Limit : 65535/32768K (Java/Other)
Total Submission(s) : 64 Accepted Submission(s) : 11
Font: Times New Roman | Verdana | Georgia
Font Size: ← →
Problem Description
新年伊始,集训队迎来了15级新生。教练打算将大家N(2<=N<=20)个人分成AB两队,已知每两个新生之间都有相互的思念值,如果分到一队的话经常见面不会思念,但是如果不被分到一队的话,他们就会无比思念对方,此时两个人之间的思念值为f(0<=f<=10000),教练想知道,分队使大家的思念值总和(即A队的每个人与B队的每个人之间的思念值的总和)达到的最大值是多少。PS:两个人如果在不同队伍才加入思念值总和
Input
多组用例,处理到EOF
对于每组用例:
第一行 N
接下来的N行,每行N个数
第i行第j个数表示i和j分到两个队时彼此的思念值
第i行第j个数等于第j行第i个数,当i=j时,思念值为0
对于每组用例:
第一行 N
接下来的N行,每行N个数
第i行第j个数表示i和j分到两个队时彼此的思念值
第i行第j个数等于第j行第i个数,当i=j时,思念值为0
Output
思念值总值的最大值
Sample Input
3 0 50 30 50 0 40 30 40 0
Sample Output
90
方法一:
枚举所有的状态数,然后一个新的状态数一定可以由已经确定的状态数改变其中的一位二进制得到
时间复杂度:2^n*n
#include <map>
#include <set>
#include <stack>
#include <queue>
#include <cmath>
#include <ctime>
#include <vector>
#include <cstdio>
#include <cctype>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
using namespace std;
#define INF 0x3f3f3f3f
#define inf -0x3f3f3f3f
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define mem0(a) memset(a,0,sizeof(a))
#define mem1(a) memset(a,-1,sizeof(a))
#define mem(a, b) memset(a, b, sizeof(a))
const int maxn=2000000;
int num[maxn];
int mp[30][30],ans[maxn];
int a[21];
int main(){
int n;
while(scanf("%d",&n)!=EOF){
mem0(num);
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
scanf("%d",&mp[i][j]);
int cnt=1<<n;
int maxv=0;
ans[0]=0;
for(int i=1;i<cnt;i++){
if(num[cnt-i]==1)
continue;
int id;
num[i]=1;
for(int j=1;j<=n;j++)
if(i&(1<<(j-1))){
ans[i]=ans[i-(1<<(j-1))];
id=j;
break;
}
for(int j=1;j<=n;j++){
if(i&(1<<(j-1)))
ans[i]-=mp[id][j];
else
ans[i]+=mp[id][j];
}
maxv=max(maxv,ans[i]);
}
printf("%d\n",maxv);
}
return 0;
}