Card Hand Sorting 二进制枚举暴力

Posted bluefly-hrbust

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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;

 

以上是关于Card Hand Sorting 二进制枚举暴力的主要内容,如果未能解决你的问题,请参考以下文章

二进制枚举+LCSCard Hand Sorting

upc 3028 Card Hand Sorting

计蒜客 17412 Card Hand Sorting 最长公共子序列

AcWing 2058. 笨拙的手指(暴力枚举)

字符串暴力枚举子序列求LCS

517-coding #1 枚举算法