CSU 2020 Card Hand Sorting (Enumeration Sorting + Longest Common Subsequence)

Reprinted from: https://blog.csdn.net/qq_38786088/article/details/79793849

Topic link: http://acm.csu.edu.cn/csuoj/problemset/problem?pid=2020

题目:
Description
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?

Input
There will be several test cases. For the each case, 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
Output the minimum number of card moves required to sort the hand as described above.

Sample Input
4
2h Th 8c Qh
7
9d As 2s Qd 2c Jd 8h
4
2h 3h 9c 8c
Sample Output
1
2
0

The meaning of the question: It is a poker card. There are no kings and kings. A maximum of 52 cards are entered. The cards are entered in order. Each card has two attributes, suit and size. The title requires that cards of the same suit should be placed together. And the cards of the same suit must be in ascending or descending order. There is no requirement for the order between different suits. Ask at least how many times to move the cards. The movement of the cards is not to exchange the positions of the two cards, but to insert them into a certain position.

* This problem is very complicated, and I always think about greed during the game! We are obsessed with finding an optimal sorting result,
but in fact, we think about the total number of results (the final sorting that satisfies the meaning of the question), (divided into 4 groups from left to right, that is, 4 types of sorting 4!,
and each group It can be in ascending or descending order, so there are 2^4, that is, the total number of solutions is 4!*2^4=24*16=384 kinds)!
** We only need to find a general method to solve: the minimum number of cards that need to be adjusted to arrange the original input sequence into a sequence that satisfies the meaning of the question.
The sequence that satisfies the meaning of the question is numbered from small to large, and the value of the row corresponding to the original sequence is this number. We need to sort the original order out of order from small to large.
We only need to find the longest ascending subsequence, other Elements that do not belong to this sequence need to be moved once to make them into a sequence that satisfies the meaning of the question!
** We have found a general method, we only need to traverse all the sequences that meet the meaning of the question, and the original sequence needs to mobilize the least cards to form, Find the smallest value of which is
ans!

Code:

#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <vector>
using namespace std;

struct node_t{
    int val;
    int suit;
    int idx;
}p[60];

int increas[6],ssort[6];
bool cmp(node_t a,node_t b){
    if(a.suit==b.suit)
       return (increas[a.suit]&&a.val<b.val)||(!increas[a.suit]&&a.val>b.val);
    return ssort[a.suit]<ssort[b.suit];
}

int Idx[60],flag[6]={0};
int DP[60];
char s[3];
int ans,n;
int S_Int_val(char a){
    if('2'<=a&&a<='9')
        return a-'1';
    if(a=='T') return 9;
    if(a=='J') return 10;
    if(a=='Q') return 11;
    if(a=='K') return 12;
    return 13;
}

int S_Int_suit(char a){
    if(a=='s') return 1;
    if(a=='h') return 2;
    if(a=='d') return 3;
    return 4;
}

void dfs(int rt){
    if(rt==0){
        sort(p,p+n,cmp);
        for(int i=0;i<n;++i)
            Idx[p[i].idx]=i;

        DP[0]=1;
        int maxn=1;
        for(int i=1;i<n;++i){
            DP[i]=1;
            for(int j=0;j<i;++j)
                if(Idx[j]<Idx[i]) DP[i]=max(DP[j]+1,DP[i]);
            maxn=max(maxn,DP[i]);
        }
        ans=min(n-maxn,ans);

    }

    for(int i=1;i<=4;++i){//枚举四种花色的排序,共24种
        if(flag[i])continue;
        flag[i]=1;
        ssort[rt]=i;
        dfs(rt-1);
        flag[i]=0;
    }
}

int main(){
    while(~scanf("%d",&n)){
        for(int i=0;i<n;++i){
            scanf("%s",s);
            p[i].val=S_Int_val(s[0]);//
            p[i].suit=S_Int_suit(s[1]);
            p[i].idx=i;
        }

        ans=1e9;
        for(int i=0;i<(1<<4);++i){
            for(int j=0;j<4;++j)
                increas[j+1]=((1<<j)&i)?1:0;//枚举每一种花色的升序和降序,共16种,1为升序,0为降序。
            dfs(4);
        }
        printf("%d\n",ans);
    }

    return 0;
}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326008489&siteId=291194637