【背包dp】团队分组UVA1627

8人阅读 评论(0) 收藏 举报
分类:

今天上午很神奇地被两个dp用小错误卡了一上午。。。

题意:给出每个人是否认识另外的人(可能单向认识),分两组让每组中的人互相认识,使两组人数差最小并输出方案

把每对不是互相认识的人连边,代表他们不能分到一个组,这样的话连通分量可能有很多个,然而各个连通分量之间是互不影响的,所以分别二分图染色就可以,然后统计两种颜色在这个连通分量里分别有多少人。这样就把人分成了k个组,每个组中可以让染黑色的人去Team1,或去Team2,这样是有差别的,比如黑色比白色多2人,如果Team1选了黑色,那么就会比Team2又多两人,反之就会少两人,这像什么?背包!但是取值可能出现负数,不能作为数组下标,那都加上一个大数就好了。bool数组dp[i][j]代表选前i组能否取到j

然后美滋滋地写完,WA,vjudge上还不给数据,还不会手写SPJ,只能自己造数据人眼对拍及其心酸,然后我终于拍出来了!多组数据dp数组没memset...多组数据真的坑,省选day2t1学长花式演示没换行没memset等各种花式爆炸。。。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
using namespace std;
struct Group{
	int N0,N1;
	int val(){
		return abs(N0-N1);
	}
}T[200000];
int n,m1,h[2020],C[2200],N1,N0,pre[2010][2010],A[20020],T1[5020],T2[5020];
bool v[2010][200],dp[2010][2010],flag;
struct edge{
	int next,to;
	void Add(int Next,int To){
		next=Next; to=To;
	}
}q[200200];
void addedge(int x,int y){
	q[++m1].Add(h[x],y); h[x]=m1;
	q[++m1].Add(h[y],x); h[y]=m1;
}
void Dfs(int x,int c){
	int i,y;
	C[x]=c;
	if (c==0) N0++;
	else N1++;
	for (i=h[x];i;i=q[i].next){
		y=q[i].to;
		if (C[y]!=-1){
			if (C[y]!=1-c){
				flag=1;
				return;
			}
			continue;
		}
		Dfs(y,1-c);
		if (flag) return;
	}
}//二分图染色
void dfs(int x,int c){
	if (C[x]==c) T1[++T1[0]]=x;
	else T2[++T2[0]]=x;
	C[x]=-1;
	
	int i,y;
	for (i=h[x];i;i=q[i].next){
		y=q[i].to;
		if (C[y]!=-1)
			dfs(y,c);
	}
}
void Work(){
	scanf("%d",&n);
	m1=0; flag=0;
	memset(v,0,sizeof(v));
	memset(h,0,sizeof(h));
	memset(q,0,sizeof(q));
	memset(C,-1,sizeof(C));
	memset(pre,0,sizeof(pre));
	memset(dp,0,sizeof(dp));
	T1[0]=T2[0]=0;
	
	int i,x,j,k=0;
	for (i=1;i<=n;i++){
		while (cin>>x){
			if (!x) break;
			v[i][x]=1;
		}
	}
	for (i=1;i<=n;i++)
		for (j=i+1;j<=n;j++)
			if (!v[i][j]||!v[j][i])
				addedge(i,j);
	for (i=1;i<=n;i++)
		if (C[i]==-1){
			A[++k]=i; N0=N1=0;
			Dfs(i,0);
			if (flag){
				printf("No solution\n"); return;
			}
			T[k].N0=N0; T[k].N1=N1;
		}
	dp[0][500]=1;//把每个个下标都+500,避免出现负权下标
	for (i=1;i<=k;i++)
		for (j=350;j<=650;j++)
			if (dp[i-1][j]){
				dp[i][j+T[i].val()]=dp[i][j-T[i].val()]=1;
				pre[i][j+T[i].val()]=i,pre[i][j-T[i].val()]=-i;
			}
	for (i=500;i<=1000;i++)
		if (dp[k][i]){//dp[k][i]写成dp[n][i]了 
			N0=i; break;
		}
	//因为如果选一个集合能取到最优解,那么选它的补集结果是一样的,所以结果对称,只从一边找就可以 
	for (i=k;i>=1;i--)
		if (pre[i][N0]<0){
			if (T[i].N0>T[i].N1) dfs(A[i],1);
			else dfs(A[i],0);
			N0+=T[i].val();
		}
		else{
			if (T[i].N0>T[i].N1) dfs(A[i],0);
			else dfs(A[i],1);
			N0-=T[i].val();
		}
	for (i=0;i<=T1[0];i++) printf("%d ",T1[i]);
	printf("\n");
	for (i=0;i<=T2[0];i++) printf("%d ",T2[i]);
	printf("\n");
}
int main(){
	int T;
	scanf("%d",&T);
	for (int i=0;i<T;i++){
		if (i) printf("\n");
		Work();
	}
}

查看评论

【项目管理】项目实战笔记之六:团队建设的三种境界

经过自己总结和项目经理们探讨,认为项目或部门团队建设可分为三个等级: 一、乌合之众,强权政治(新手)        很多新手都会经历这样的过程,新组建的团队冲突不断,大家对当各种制度措施,报以反感...
  • liangjingbo
  • liangjingbo
  • 2012-07-02 18:29:27
  • 2723

项目团队中4种组员类型的相应管理方式

在我们的实际软件项目中,管理团队其实比写代码或者实现一个客户的需求更为的有挑战性。因为编程实际上是和机器打交道,而和机器打交道,只要你符合机器预定的逻辑, 一步步迈向解决问题的道路上一点都不难,但是人...
  • chancein007
  • chancein007
  • 2014-06-13 23:40:24
  • 1760

01背包问题(DP解决)

问题主题:著名的01背包问题 问题描述: 有n个重量和价值分别为wi、vi的物品,现在要从这些物品中选出总重量不超过W的物品,求所有挑选方案中的价值最大值。 限制条件: 1...
  • qq_31828929
  • qq_31828929
  • 2016-09-03 21:07:39
  • 626

UVA 1627 Team them up!

题目链接:http://acm.hust.edu.cn/vjudge/problem/51188 题意:n个人要分为两组,每个组都不可以为空,给出这n个人的关系(单向的),要求分完组之后,每...
  • chy20142109
  • chy20142109
  • 2016-08-19 00:33:18
  • 255

uva1627(模型转换01背包)

题意:有n(n 解法:如果两人不是相互都认识,就连一条无向边。所以就变成了一个无向图。对于每一个连通分量来说,必须是个二分染色图,否则就No solution。然后对于每个联通分量,黑白两种...
  • xiefubao
  • xiefubao
  • 2014-12-01 16:31:07
  • 995

笔试题——团队活动分组

现有n个人,每个人有一个唯一的数字作为标签,标签数字的范围:1~n;为了统计分组情况,有人提议有分组意愿的人提交一个数字,表示其会和以该数字为标签的人分到一组。 现在知道每个人的选择,您能统计出一共有...
  • qq_28618765
  • qq_28618765
  • 2017-09-18 17:38:46
  • 313

DP背包之01背包、完全背包、多重背包笔记

这是个经典话题,值得好好研究一番,本文作为学习笔记将会不断更新。 主要参考了以下资料: 背包问题九讲:http://love-oriented.com/pack/Index.html 背包之...
  • hellobinfeng
  • hellobinfeng
  • 2013-12-23 13:32:36
  • 3131

Team them up! UVA - 1627(动态规划+好题)

题目大意: 给你n个数字,让你将数字分成两组。是的两组的数字个数尽可能相近。规则如下:每个数字有各自认识的其他数字,每个数字只能和他认识的数字在一组。求分配方式。 题目链接:https://vju...
  • lwgkzl
  • lwgkzl
  • 2017-09-30 19:29:10
  • 522

Uva-1627 Team them up!(背包变形)

题意:有(n 分析:把所有不互相认识的人之间连一条边,然后问题就变成了让我们对整个图黑白染色,且要求同色点之间不能有边,如果原图不是二分图则直接无解,否则在每个连通分量中染色后dp。 ...
  • u014258433
  • u014258433
  • 2017-03-13 20:04:26
  • 255

数据库查询分组类型问题总结

源数据         名称       分数                         ----   -----------       a             1     a      ...
  • pfworld
  • pfworld
  • 2007-05-30 17:59:00
  • 654
    个人资料
    持之以恒
    等级:
    访问量: 441
    积分: 296
    排名: 26万+
    文章存档
    最新评论