Block Voting --解题报告

    这道题做的有点狼狈,效率不高,差一点就TLE的AC了。看status里的,AC的时间大多数都是0ms的。肯定有一个更有效率的算法的。下面说下我的狼狈算法。

 

 

出处:http://acm.jlu.edu.cn/joj/showproblem.php?pid=1223

 

 

问题描述:

求每个party的权值。

第i个party的权值定义:除去第i个party的投票。其他party的分成二组,设其二组的票数分别为s1,s2。

则s1<=s2,且有s1+party的票数>=s2的那些组合个数,为其权值。

 

输入:

 case个数。

每个case,输入n,再输入n个party的票数。

 

输出:

对应于每个case中,第个party的权值。

 

思路:

由上面的式子,求出s1的范围,再对s1对数组里查找能不能组成它的组合。

这里又用到了回溯,时间效率超低。

现在还想不出其他方法。

 

代码:

#include <stdio.h> int n,a[21]; int visit[21]; int key; int t; int Ofkey[21]; void solve(int data,int k) { if(data==0) { key++; return ; } if(k==t) {solve(data,k+1);return;} if(k==n) return; solve(data,k+1); if(data>=a[k]) { solve(data-a[k],k+1); } } int main() { int k; int i,j; int s; int x,y,p; int num; scanf("%d",&k); while(k--) { scanf("%d",&n); s=0; for(i=0;i<n;i++) {scanf("%d",&a[i]);s+=a[i];} for(i=0;i<n;i++) { for(p=0;p<i;p++) { if(a[i]==a[p]) break; } if(p==i) { if(s%2==0) x=s/2-a[i]; else x=s/2-a[i]+1; if(x<0) x=0; y=(s-a[i])/2; t=i; num=0; for(j=x;j<=y;j++) { key=0; solve(j,0); if(a[i]+j==s-a[i]-j||j==s-a[i]-j); else key=key*2; num+=key; } Ofkey[i]=num; } else Ofkey[i]=Ofkey[p]; printf("party %d has power index %d/n",i+1,Ofkey[i]); } printf("/n"); } return 0; }

 

你可能感兴趣的:(Block Voting --解题报告)