一、题意
随机给你一堆牌(标准扑克牌),之后让你按照:
第一优先规则:所有相同花色的在一起
第二优先规则:所有相同花色的必须按照升序或者降序排列
问,你最少要拿出多少张牌插入到其他的地方以维持这个状况?
二、做法
考虑,4种花色,因而排列有A44(24种);
考虑升降续组合,为2^4=16种
因而所有合法最终状态共有24*16种状态,因而可以进行枚举。
对于变化次数有,n-LCS(i);
故,枚举取最大即可。
最大时间复杂度为:
52*52+14*16*52*log52;
(因为最大卡牌数量为52)
三、代码
#include<iostream> #include<math.h> #include<stdio.h> #include<stdio.h> #include<stdlib.h> #include<vector> #include<string> #include<string.h> #include<algorithm> using namespace std; #define ll long long #define veci vector<int> #define pp pair<ll,ll> #define vecp vector<pp> const ll MAXN=233; int c[]={‘c‘,‘h‘,‘s‘,‘d‘}; bool state[4]; char control[24][4]; vector<char> que; int times=0; const int ENDD=16; void dfs(int dep) { if(dep == 4) { int len=que.size(); for(int i=0;i<len;++i) { control[times][i]=que[i]; } times++; }else{ for(int i=0;i<4;++i) { if(state[i]==0) { state[i]=1; que.push_back(c[i]); dfs(dep+1); state[i]=0; que.pop_back(); } } } } ll n; class Card { public: char color; int num; Card(){} Card(char a,int b):color(a),num(b){} Card(string str) { color = str[1]; char tar = str[0]; if(tar>=‘0‘&&tar<=‘9‘)num=tar - ‘0‘; if(tar == ‘T‘)num=10; if(tar == ‘J‘)num=11; if(tar == ‘Q‘)num=12; if(tar == ‘K‘)num=13; if(tar == ‘A‘)num=14; } const bool operator == (Card c) { return color==c.color&&num==c.num; } }; bool cmp_1 (Card c1,Card c2) { return c1.num<c2.num; } bool cmp_2(Card c1,Card c2) { return c1.num>c2.num; } Card cards[MAXN]; Card arr[ENDD][24][MAXN]; Card tmp[4][MAXN]; int points[4]; int search_number(char tar) { for(int i=0;i<4;++i) { if(tar == c[i])return i; }return -1; } int lcs(int a,int b) { int dp[MAXN][MAXN]; memset(dp,0,sizeof(dp)); for(int i=0;i<n;++i) { for(int j=0;j<n;++j) { int x=i+1;int y=j+1; if(arr[a][b][i] == cards[j]) dp[x][y]=dp[x-1][y-1]+1; else dp[x][y]=max(dp[x-1][y],dp[x][y-1]); } } return dp[n][n]; } void init() { memset(cards,0,sizeof(cards)); memset(arr,0,sizeof(arr)); memset(points,0,sizeof(points)); int res=0; for(int i=0;i<n;++i) { string str; cin>>str; cards[i] = Card(str); } for(int i=0;i<n;++i) { for(int j=0;j<4;++j) { if(cards[i].color == c[j]) { tmp[j][points[j]++]=cards[i]; break; } } } for(int i=0;i<24;++i) { int point=0; for(int j=0;j<4;++j) { char now = control[i][j]; int number = search_number(now); int start=point; for(int k=0;k<points[number];++k) { for(int m=0;m<ENDD;++m) { arr[m][i][point]=tmp[number][k]; } point++; } for(int m=0;m<ENDD;++m) { int k = 1<<j; if(k&m) { sort(arr[m][i]+start,arr[m][i]+point,cmp_1); }else sort(arr[m][i]+start,arr[m][i]+point,cmp_2); } } } for(int i=0;i<ENDD;++i) { for(int j=0;j<24;++j) { res=max(res,lcs(i,j)); } } cout<<n-res<<endl; } int main() { cin.sync_with_stdio(false); dfs(0); while(cin>>n)init(); // cout<<3)<<endl; return 0; }