Card Hand Sorting 二進制枚舉暴力

  這個題其實由於只有4種花色的,那麼每種花色排列的順序,也不過是4!種,然後對於每種花色內部到底是升序還是降序,其實也可以直接暴力,一共也就4!*2^4種情況,然後直接進行排序就可以了,但是我們如何計算需要移動的位置呢???我們這樣考慮,我們由於要保證內部有序,那麼最後一定是一個升序或者降序,那麼插入一張牌,實際上是相當改變內部相對位置,那麼考慮無序的,我們肯定是找到最長的遞增子序列,那麼他們一定是不用互相移動的,而其他的肯定是要移動的,因爲他們不滿足前後的順序,並且他們是肯定是要移動的,直接二進制枚舉即可。

#include<iostream>
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
struct node{
   int id;
   int val;
   int col;
   int flag;
}a[105];
int dp[69];
int col[4]={0,1,2,3};
char s[105];
int n;
bool cmp(node x,node y){
   if (x.col==y.col){
      return x.flag<y.flag;
   }
   return col[x.col]<col[y.col];
}
int LCS(){
    memset(dp,0,sizeof(dp));
    int ans=1;
    for (int i=1;i<=n;i++){
        dp[i]=1;
        for (int j=1;j<i;j++){
            if (a[i].id>a[j].id){
                dp[i]=max(dp[i],dp[j]+1);
            }
        }
        ans=max(ans,dp[i]);
    }
    return ans;
}
int main(){
  while(~scanf("%d",&n)){
  int ans=0x3f3f3f3f;
  for (int i=1;i<=n;i++){
     scanf("%s",s);
     if (s[0]=='T')
        a[i].val=10;
     else if (s[0]=='J')
        a[i].val=11;
     else if (s[0]=='Q')
        a[i].val=12;
     else if (s[0]=='K')
        a[i].val=13;
     else if (s[0]=='A')
        a[i].val=14;
     else
        a[i].val=s[0]-'0';
     if (s[1]=='s')a[i].col=0;
     else if (s[1]=='h')a[i].col=1;
     else if (s[1]=='d')a[i].col=2;
     else a[i].col=3;
     a[i].id=i;
  }
  //cout<<"sssssss";
  do{
    for (int i=1;i<16;i++){
        for (int j=1;j<=n;j++){
             a[j].flag=a[j].val*(((i>>col[a[j].col])&1)?1:-1);
        }
        sort(a+1,a+1+n,cmp);
        int minn=n-LCS();
        ans=min(ans,minn);
    }

  }while(next_permutation(col,col+4));
  printf("%d\n",ans);
  }
  return 0;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章