CSUoj 2020 Card Hand Sorting 最长递增序列 暴力枚举

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

题意:
一手扑克牌, 最多52张 要将扑克牌排序 相同花色放在一起并要有序排列, 不同花色之间互不影响。
定义一次操作为: 选中一张牌 将它插入至想要的位置。
问最少进行多少次操作可以排序完成。
解题思路:
没写出来,看的题解。 太菜了 太菜了。
首先要想到 对于初始状态,我们并不知道最终状态是什么样的才是最优的。 所以这一部分要枚举。
最多有52!种最终状态 直接暴力枚举肯定会超时。 然后 想到如何减少最终状态。
合法状态抽象出来就两点
1、 分成4块
2、 每块内部是有序的。
这样的话,状态就很好枚举了。 最多有4!*2^4 种状态 可以说是非常少了。
那么 当知道了最终该状态后 , 该如何确定到达该状态的最少步数呢。
其实 可以很容易的想到,每张牌做最多只要移动一次 就肯定可以到达目标位置(不懂可以找副排模拟一下)
那么 我们只要找到哪些排不用移动就好了。 这就转化成了最长递增子序列。
这样暴力枚举的话 复杂度为O(4!*2^4*n^2) 不超过1e6 显然满足要求。

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
#define LL long long
using namespace std;
const int MAX = 1e6+4;
class Node {
public:
    int id,ranks;
    Node(int id,int ranks):id(id),ranks(ranks) {}
    bool operator < (const Node &b)const {
        return ranks>b.ranks;
    }
};
int n,m;
int node[60];
int order[4];
int ans=1e9+7;
vector<Node> V[4];
int dp[60];
int getans(int s) {
    int tot=0;
    for(int i=0; i<4; i++) {
        if(s&(1<<i)) {
            for(int j=0; j<V[order[i]].size(); j++) {
                node[tot]=V[order[i]][j].id;
                tot++;
            }
        } else {
            for(int j=V[order[i]].size()-1; j>=0; j--) {
                node[tot]=V[order[i]][j].id;
                tot++;
            }
        }
    }
    int cnt=1;
    dp[0]=1;
    for(int i=1; i<n; i++) {
        dp[i]=1;
        for(int j=0; j<i; j++) {
            if(node[j]<node[i]) dp[i]=max(dp[j]+1,dp[i]);
        }
        cnt=max(cnt,dp[i]);
    }
    return n-cnt;
}
int maps[666];
void init() {
    ans=1e9+7;
    for(int i=0; i<4; i++) {
        V[i].clear();
        order[i]=i;
    }
    for(int i=0; i<10; i++) {
        maps[i+'0']=i;
    }
    maps['T']=10;
    maps['J']=11;
    maps['Q']=12;
    maps['K']=13;
    maps['A']=14;
    maps['s']=0;
    maps['h']=1;
    maps['d']=2;
    maps['c']=3;
}
char op[3];
int main() {
    while(~scanf("%d",&n)) {
        init();
        for(int i=0; i<n; i++) {
            scanf("%s",op);
            V[maps[op[1]]].push_back(Node(i,maps[op[0]]));
        }
        for(int i=0; i<4; i++) {
            sort(V[i].begin(),V[i].end());
        }
        for(int i=0; i<(1<<4); i++) {
            for(int j=0; j<1*2*3*4; j++) {
                ans=min(ans,getans(i));
                next_permutation(order,order+4);
            }
        }
        cout<<ans<<endl;
    }
}

猜你喜欢

转载自blog.csdn.net/lifelikes/article/details/79809064
今日推荐