//突然想把以前没a的题a掉。
题目大意:
n支足球队两两各比赛一场,若平局各加1分,否则赢的队伍加3分,属的队伍加0分,目前知道各个队伍最终得分,要输出可能的情况数目。(100%的数据满足3≤N≤10且至少存在一组解)
思路:
首先,这是一道搜索题。搜索顺序是,枚举每一个队伍与其之后的的队伍之间的输赢状况。
考虑到一下几点:
*用hash[]记录每个状态下的可能情况数,再次搜到时可以直接用。
*对于任意一个状态,还没有枚举过与其他队打的那些队伍,可以随意交换顺序,并不影响结果,每次搜到一支队伍满足条件后,进行一次排 序,再搜索下一个队伍。
*每平一局会使总分加2,每有一局分出胜负,总分加3,而目前已知最终总分与总局数,那么类似鸡兔同笼,可求出平局数与有胜负的局数。
具体实现的做法标在代码里了。
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #include<map> 5 6 using namespace std; 7 8 struct node 9 { 10 int a[12];//a[0]表示当前在搜索哪个队伍,a[1]~a[n]表示目前队伍剩余得分。 11 node() 12 { 13 memset(a,0,sizeof(a)); 14 } 15 }st; 16 17 map <long long,int>hash; 18 const int p=1000000007; 19 int n,ying,ping; 20 21 long long geth(node x) 22 { 23 long long ret=0; 24 for(int i=0;i<=n;i++)ret=ret*28+x.a[i];//一个队最多得27分。 25 return ret; 26 } 27 28 int dfs(int i,node now,int win,int low)//now.a[0]与i比赛 29 { 30 if((win>ying)||(low>ping))return -1; 31 if(now.a[0]==n) //已经是最后一个队,比赛还没结束,那么此状态不可行 32 { 33 return -1; 34 } 35 if(now.a[now.a[0]]>3*(n-i+1))//即使now.a[0]之后全赢也不满足now,也不可行 36 { 37 return -1; 38 } 39 if(i>n&&now.a[now.a[0]]==0) 40 { 41 now.a[0]++; 42 sort(now.a+1,now.a+1+n);//顺序不影响 43 if(hash[geth(now)])return hash[geth(now)]; 44 else 45 { 46 hash[geth(now)]=dfs(now.a[0]+1,now,win,low); 47 return hash[geth(now)]; 48 } 49 } 50 int id=now.a[0],tem,ans=0; 51 if(now.a[id]>=3) 52 { 53 now.a[id]-=3; 54 tem=dfs(i+1,now,win+1,low); 55 if(tem!=-1)ans=(ans+tem)%p; 56 now.a[id]+=3; 57 } 58 if(now.a[id]&&now.a[i]) 59 { 60 now.a[id]--; 61 now.a[i]--; 62 tem=dfs(i+1,now,win,low+1); 63 if(tem!=-1)ans=(ans+tem)%p; 64 now.a[id]++; 65 now.a[i]++; 66 } 67 if(now.a[i]>=3) 68 { 69 now.a[i]-=3; 70 tem=dfs(i+1,now,win+1,low); 71 if(tem!=-1)ans=(ans+tem)%p; 72 now.a[i]+=3; 73 } 74 if(!ans)ans=-1; 75 if(i==id+1)hash[geth(now)]=ans; 76 return ans; 77 } 78 79 80 int main() 81 { 82 scanf("%d",&n); 83 for(int i=1;i<=n;i++)scanf("%d",&st.a[i]); 84 sort(st.a+1,st.a+1+n); 85 int sum=0; 86 for(int i=1;i<=n;i++)sum+=st.a[i]; 87 ping=3*n*(n-1)/2-sum;//剪枝:求出平了几局,赢了几局(鸡兔同笼)。 88 ying=sum-n*(n-1); 89 node tem; 90 tem.a[0]=n; 91 hash[geth(tem)]=1; //初始化。搜完第n个队伍,各个队伍的得分都为零,这种情况下答案为1。 92 st.a[0]=1; 93 int iss=dfs(2,st,0,0); 94 printf("%d\n",iss); 95 return 0; 96 }
原文:https://www.cnblogs.com/LiqgNonqfu/p/9874060.html