题意:两个人打牌,牌的大小按照2,3,4...9,T,J,Q,K,A排序,如果点数相等就按照H>S>D>C的花色排序。告诉你第一个人的手牌,让你安排第二个人的手牌,使得得分最大(按照顺序依次比较每张牌大小)
题解:先建立两人牌比较的二分图,就是第二个人的第i张牌如果比第一个人第j张牌大,就建立i->j的边,然后求一次二分匹配得答案。
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 using namespace std; 5 bool g[30][30],chk[30]; 6 int link[30],n; 7 bool findpath(int x) 8 { 9 for(int y=0;y<n;y++) 10 { 11 if(g[x][y]&&!chk[y]) 12 { 13 chk[y]=true; 14 if(link[y]==-1||findpath(link[y])) 15 { 16 link[y]=x; 17 return true; 18 } 19 } 20 } 21 return false; 22 } 23 int maxmatch() 24 { 25 memset(link,-1,sizeof(link)); 26 int ret=0; 27 for(int x=0;x<n;x++) 28 { 29 memset(chk,false,sizeof(chk)); 30 if(findpath(x)) 31 ret++; 32 } 33 return ret; 34 } 35 int op[150]; 36 bool small(char s1[],char s2[]) 37 { 38 if(op[s1[0]]!=op[s2[0]]) 39 return op[s1[0]]<op[s2[0]]; 40 else 41 return op[s1[1]]<op[s2[1]]; 42 } 43 int main() 44 { 45 for(int i=2;i<=9;i++) 46 op[i+'0']=i; 47 op['T']=10;op['J']=11;op['Q']=12;op['K']=13;op['A']=14; 48 op['C']=1;op['D']=2;op['S']=3;op['H']=4; 49 int T; 50 for(scanf("%d",&T);T;T--) 51 { 52 scanf("%d",&n); 53 memset(g,false,sizeof(g)); 54 char s1[30][3],s2[30][3]; 55 for(int i=0;i<n;i++) 56 scanf("%s",s1[i]); 57 for(int i=0;i<n;i++) 58 { 59 scanf("%s",s2[i]); 60 for(int j=0;j<n;j++) 61 if(small(s1[j],s2[i])) 62 g[i][j]=true; 63 } 64 printf("%d\n",maxmatch()); 65 } 66 return 0; 67 }