1. 程式人生 > >NCPC2016--C Card Hand Sorting(upc 3028)

NCPC2016--C Card Hand Sorting(upc 3028)

題目描述 When dealt cards in the card game Plump it is a good idea to start by sorting the cards in hand by suit and rank. The different suits should be grouped and the ranks should be sorted within each suit. But the order of the suits does not matter and within each suit, the cards may be sorted in either ascending or descending order on rank. It is allowed for some suits to be sorted in ascending order and others in descending order. Sorting is done by moving one card at a time from its current position to a new position in the hand, at the start, end, or in between two adjacent cards. What is the smallest number of moves required to sort a given hand of cards?

輸入

The first line of input contains an integer n (1 ≤ n ≤ 52), the number of cards in the hand. The second line contains n pairwise distinct space-separated cards, each represented by two characters. The first character of a card represents the rank and is either a digit from 2 to 9 or one of the letters T , J , Q , K , and A representing Ten, Jack, Queen, King and Ace, respectively, given here in increasing order. The second character of a card is from the set { s , h , d , c } representing the suits spades ♠, hearts ♥, diamonds ♦, and clubs ♣.

輸出

Output the minimum number of card moves required to sort the hand as described above.

樣例輸入 7 9d As 2s Qd 2c Jd 8h

樣例輸出 2

懶人又來更博了。

題意: 有一重撲克(沒有大小王)總共52張。其中有♣♥♦♠四種花色,還有2-A 這13中rank。讓你先把花色相同的聚集在一起(四個花色順序任意),每個花色裡再按rank遞增或遞減排序。 給你一串撲克,讓你移動(選擇一張牌將它放在任意位置)最少數量的牌,使當前撲克有序(指符合上面所說的排序方案)。最後輸出移動的撲克數量。

思路

  1. 四個花色的順序有4!=24種
  2. 每個花色的升序或降序又有2^4=16種
  3. 總共有24*16種可以的順序。列舉這些順序,找到當前撲克按此順序最大的不用移動的數量(即按當前列舉順序的最大上升子序列)。

程式碼:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e5+7;
const ll mod=1e9+7;
ll qpow(ll x,ll y){ll ans=1;while(y){if(y%2) ans=ans*x%mod; x=x*x%mod;y/=2;}return ans;}
char s[55][3];
int order[4]={0,1,2,3};
char suit[4]={'s','h','d','c'};
int key[4];
int dp[55]={0};
char cards[13]={'2','3','4','5','6','7','8','9','T','J','Q','K','A'};
int cmp(char x[3],char y[3],int order[4],int key[4]){

    for(int i=0;i<4;i++)
    {
        if(suit[order[i]]==x[1]&&suit[order[i]]==y[1]){
            int o=key[order[i]];
            if(o==0){//降序
                for(int j=0;j<13;j++){
                    if(x[0]==cards[j]){
                        return 1;
                    }
                    if(y[0]==cards[j]) return -1;
                }
            }
            else{//升序
                for(int j=0;j<13;j++){
                    if(x[0]==cards[j]){
                        return -1;
                    }
                    if(y[0]==cards[j]) return 1;
                }
            }
        }
        else if(suit[order[i]]==x[1])
        {
            return -1;
        }
        else if(suit[order[i]]==y[1]) return 1;
    }
    return 1;
}
int main()
{
    int n;
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
        scanf("%s",s[i]);
    }
    int Max=0;
    do{
        int t=1<<4;
        for(int i=0;i<t;i++){
            int temp=i;
            for(int j=0;j<4;j++){
                key[j]=temp%2;//0降序,1升序
                temp/=2;
            }
            memset(dp,0,sizeof(dp));
            for(int k=1;k<=n;k++)
            {
                dp[k]=1;
                for(int j=1;j<k;j++){
                    if(cmp(s[j],s[k],order,key)<0&&dp[k]<dp[j]+1)
                        dp[k]=dp[j]+1;
                }
            }
            for(int i=1;i<=n;i++)
            Max=max(Max,dp[i]);
        }
    }while(next_permutation(order,order+4));//懶得直接用了全排列函式求了四個花色的順序
    cout<<n-Max<<endl;
    return 0;
}