南邮 OJ 2030 收购计划

收购计划

时间限制(普通/Java) :  2000 MS/ 6000 MS          运行内存限制 : 16384 KByte
总提交 : 361            测试通过 : 37 

比赛描述

IT巨子松老师经过数十年的奋斗,终于打败了所有竞争对手准备一统IT界。此时除了松老师的帝国之外还有N个残存的小公司,松老师打算收购其中的一些。这些公司有a1、a2…an个员工,收购之后松老师打算把员工分给总裁办的K个助理进行管理,为了防止内部矛盾,松老师希望每个助理分到的员工数量都相同。松老师想知道自己最多可以收购多少家公司,使得总的员工数可以平均分配呢?



输入

第一行为一个正整数T,表示有T组数据(T<=20)

每组数据第一行为两个正整数n,k,表示有n家公司(n<=40),以及助理的人数(k<=1000000)

接下来的一行是n个正整数,表示每家公司的员工人数(ai<=5000000)

  

输出

一个整数m表示最多可以收购多少家公司

样例输入

2

3 3

1 2 3

5 7

1 10 10 10 10

样例输出

3


题目来源

LY:D






#include<iostream>

int n,k;
int a[40];		//第i加公司的人数
int sum[40];	//[0,i]公司的总人数

//从前面[0,i]加公司中选择m家,使得这m家的人数和 + currentSum 可以整除 k
bool dfs(int i, int m, int currentSum){
	if(0==m && 0==currentSum){
		return 1;
	}
	if(i<0 || i+1<m || (currentSum && currentSum+sum[i]<k)){  //WA 当currentSum==0时,currentSum+sum[i]<k 也是可以的
		return 0;
	}
	return (dfs(i-1,m-1,(currentSum+a[i])%k) || dfs(i-1,m,currentSum) );
}
int main(){
	freopen("test.txt","r",stdin);
	int T,i,m;
	scanf("%d",&T);
	while(T--){
		scanf("%d%d",&n,&k);
		scanf("%d",a);
		a[0] %= k;
		sum[0] = a[0];
		for(i=1;i<n;i++){
			scanf("%d",a+i);
			a[i] %= k;
			sum[i] = sum[i-1]+a[i];
		}
		for(m=n;m>0;m--){
			if(dfs(n-1,m,0)){
				break;
			}
		}
		printf("%d\n",m);
	}
}



你可能感兴趣的:(ACM,收购计划,南邮OJ)