Card Hand Sorting Gym - 101550C(枚舉+LIS)

在這裏插入圖片描述
題意:
n個卡牌,每個卡牌有值和種類,你可以任意調換某張卡牌的順序,要求使得每個種類的卡牌在一起,且爲有序(遞增或遞減)

思路:
枚舉屬性的順序以及是遞增還是遞減。
然後尋找與原串的LIS。LIS代表最大不需要改變的部分。

#include <cstdio>
#include <cstring>
#include <vector>
#include <map>

using namespace std;
typedef long long ll;

const int INF = 0x3f3f3f3f;
int n;
map<char,int>mp;
struct Node {
    int val;
    int dat;
    int id;
    int v;
}a[105];

int dp[105];

int cmp(Node a1,Node a2) {
    if(a1.v == a2.v) return a1.val < a2.val;
    return a1.v < a2.v;
}

void init() {
    for(int i = 2;i <= 9;i++) {
        mp['0' + i] = i;
    }
    mp['T'] = 10;
    mp['J'] = 11;
    mp['Q'] = 12;
    mp['K'] = 13;
    mp['A'] = 14;
    
    mp['s'] = 0;
    mp['h'] = 1;
    mp['d'] = 2;
    mp['c'] = 3;
}

int DP() {
    memset(dp,0,sizeof(dp));
    int res = 0;
    dp[1] = 1;
    for(int i = 2;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);
        }
        res = max(res,dp[i]);
    }
    return res;
}

int main() {
    scanf("%d",&n);
    for(int i = 1;i <= n;i++) {
        char s[10];scanf("%s",s);
        a[i].val = mp[s[0]];
        a[i].dat = mp[s[1]];
        a[i].id = i;
    }
    int arr[10] = {0,1,2,3};
    int ans = INF;
    
    do {
        for(int i = 0;i < (1 << 4);i++) {
            for(int j = 1;j <= n;j++) {
                a[j].v = arr[a[j].dat];
                if(i & (1 << a[j].v)) {
                    a[j].val = abs(a[j].val) * -1;
                }
                else {
                    a[j].val = abs(a[j].val);
                }
                sort(a + 1,a + 1 + n,cmp);
                ans = min(ans,n - DP());
            }
        }
    }while(next_permutation(arr,arr + 4));
}

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