31JDJH25D TC4C 5H32H 3H 4H2D 3D 4D Sample Output112题目大意:
给你和你朋友一人n张牌,你知道你朋友的出牌顺序,问你怎么安排你的出牌顺序才能使你的得分最高,输出最高得分,两张牌如果点数相同则按花色,如果都相同都不得分,具体见题目描述
题目思路:
这题其实就是田忌赛马的变形体,可以用贪心做,也可以用二分图做,这里我用的是二分图,首先我们考虑怎么建图,我们知道最后是要你的得分最高,所以如果你的牌的大于他的牌那么你可以连一条边,你的牌为一个集合,他的牌为一个集合,最后的模型就是选取最少的点使得所有边的至少一个端点被选中,即最小点覆盖模型,而最小点覆盖就是最大匹配,所以我们进行最大匹配的答案就是我们要求的
AC代码:
#include<cstring>#include<cstdio>const int maxn = 30;bool vis[maxn],mp[maxn][maxn];int link[maxn];int com[127];int n;bool dfs(int u){ for(int i=1;i<=n;i++){ if(!vis[i]&&mp[u][i]){ vis[i]=true; if(link[i]==-1||dfs(link[i])){ link[i]=u; return true; } } } return false;}int main(){ com['H'-'1']=4,com['S'-'1']=3,com['D'-'1']=2,com['C'-'1']=1; //预处理牌的大小 com['1'-'1']=1,com['2'-'1']=2,com['3'-'1']=3,com['4'-'1']=4; com['5'-'1']=5,com['6'-'1']=6,com['7'-'1']=7,com['8'-'1']=8; com['9'-'1']=9,com['T'-'1']=10,com['J'-'1']=11,com['Q'-'1']=12; com['K'-'1']=13,com['A'-'1']=14; int t;scanf("%d",&t); while(t--){ scanf("%d",&n); memset(link,-1,sizeof(link)); memset(mp,false,sizeof(mp)); char str[30][5]; for(int i=1;i<=n;i++){ scanf("%s",str[i]); } for(int i=1;i<=n;i++){ char ch[5]; scanf("%s",ch); for(int j=1;j<=n;j++){ if(com[ch[0]-'1']>com[str[j][0]-'1']||com[ch[0]-'1']==com[str[j][0]-'1']&&com[ch[1]-'1']>com[str[j][1]-'1']) mp[i][j]=true; } } int ans = 0; for(int i=1;i<=n;i++){ memset(vis,false,sizeof(vis)); if(dfs(i))ans++; } printf("%d/n",ans); } return 0;}
新闻热点
疑难解答