一、题意
随机给你一堆牌(标准扑克牌),之后让你按照:
第一优先规则:所有相同花色的在一起
第二优先规则:所有相同花色的必须按照升序或者降序排列
问,你最少要拿出多少张牌插入到其他的地方以维持这个状况?
二、做法
考虑,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;
}