Hdu 1557 权利指数(dfs)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1557
这题目刚开始读题的时候就觉得挺难的,就先去做其他题目了,后面重新看了一遍,发现每组数据的n最大只有20,那就直接dfs开搜了,第一遍搜完发现输出比样例输出大了很多倍,检查了一下发现应该出现了重复。例如:dfs会取的顺序为: 5 7 4或者 7 5 4,但是这两种其实是一样的,所以重新写了一份,发现又变得比样例少了,然后发现是在找到关键加入者就退出了当前循环,这就导致了很多可以组成的被跳出了,最后的代码如下:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int n,sum,cnt,v[25],vis[25],p[25];
inline void dfs(int res,int num,int f){//f表示for开始的位置,因为前面的一定已经被搜过了
if(num*2>sum)return;//如果当前团体票数已经超过一半,就不需要其他团体加入了,所以跳出
if(num*2<=sum&&(num+res)*2>sum){//找到了一个符合条件就加上
cnt++;
//这里不能return,因为可能还能加入一些票数低的团体
}
for(int i=f;i<n;i++){
if(vis[i]==0){
vis[i]=1;
dfs(res,num+v[i],i+1);
vis[i]=0;
}
}
}
int main(){
int t;
scanf("%d",&t);
while(t--){
scanf("%d",&n);
sum=0;
for(int i=0;i<n;i++){
scanf("%d",&v[i]);
sum+=v[i];
}
sum;
for(int i=0;i<n;i++){//搜索每一个小团体的指数
cnt=0;
vis[i]=1;
dfs(v[i],0,0);
vis[i]=0;
p[i]=cnt;
}
for(int i=0;i<n;i++){
if(i!=0)printf(" ");
printf("%d",p[i]);
}
printf("\n");
}
return 0;
}