upc 3028 Card Hand Sorting

Card Hand Sorting

时间限制: 1 Sec  内存限制: 64 MB
提交: 66  解决: 23
[提交] [状态] [讨论版] [命题人:外部导入]

题目描述


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

题意

去掉的大小王的扑克牌,要求对给出扑克排序,你每次可以拿出一张牌,插到任意位置,重复此操作直到序列有序。有序定义为:相同花色必须在一起,相同花色必须升序或者降序,不同的花色之间没有要求。

分析 

  • 总共四种花色,每种花色的牌的摆放顺序只有两种,我们显然可以枚举出最终所有的有序状态:
    ①按花色的先后顺序有4!共有24种可能。
    ②按每种花色的排序方式共有2⁴种可能。
  • 我们求解初始状态到各个最终状态之间个最少操作数,更新最小值就是结果。
  • 问题转换为:给定两个序列,求按上述调整方法由一个序列得到另外一个序列需要的最少操作数。
  • 我这里没有用4中提到的方法,而是直接求两个序列的最长公共子序列,然后总序列长度减去子序列的长度就是需要操作的最少次数。
///  author:Kissheart  ///
#include<stdio.h>
#include<algorithm>
#include<iostream>
#include<string.h>
#include<vector>
#include<stdlib.h>
#include<math.h>
#include<queue>
#include<deque>
#include<ctype.h>
#include<map>
#include<set>
#include<stack>
#include<string>
#define INF 0x3f3f3f3f
#define FAST_IO ios::sync_with_stdio(false)
const double PI = acos(-1.0);
const double eps = 1e-6;
const int MAX=1e5+10;
const int mod=1e9+7;
typedef long long ll;
using namespace std;
#define gcd(a,b) __gcd(a,b)
inline ll lcm(ll a,ll b){return a/gcd(a,b)*b;}
inline ll qpow(ll a,ll b){ll r=1,t=a; while(b){if(b&1)r=(r*t)%mod;b>>=1;t=(t*t)%mod;}return r;}
inline ll inv1(ll b){return qpow(b,mod-2);}
inline ll exgcd(ll a,ll b,ll &x,ll &y){if(!b){x=1;y=0;return a;}ll r=exgcd(b,a%b,y,x);y-=(a/b)*x;return r;}
inline ll read(){ll x=0,f=1;char c=getchar();for(;!isdigit(c);c=getchar()) if(c=='-') f=-1;for(;isdigit(c);c=getchar()) x=x*10+c-'0';return x*f;}
//freopen( "in.txt" , "r" , stdin );
//freopen( "data.txt" , "w" , stdout );
int dp[55][55],n;
int order[4]={0,1,2,3};
char a[2];
map<char,int>mp;
vector<int>v[5],s,t;

int main()
{
    mp['s']=0;mp['h']=1;mp['d']=2;mp['c']=3;mp['2']=0;mp['3']=1;mp['4']=2;mp['5']=3;mp['6']=4;
    mp['7']=5;mp['8']=6;mp['9']=7;mp['T']=8;mp['J']=9;mp['Q']=10;mp['K']=11,mp['A']=12;

    s.push_back(0);
    t.push_back(0);

    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
        scanf("%s",a);
        s.push_back(mp[a[0]]+mp[a[1]]*13);
        v[mp[a[1]]].push_back(mp[a[0]]+mp[a[1]]*13);
    }

    sort(v[0].begin(),v[0].end());
    sort(v[1].begin(),v[1].end());
    sort(v[2].begin(),v[2].end());
    sort(v[3].begin(),v[3].end());

    int ans=INF;
    do
    {
        for(int i=0;i<16;i++)
        {
            for(int j=0;j<4;j++)
            {
                if(!v[order[j]].size()) continue;

                if((i>>j)&1)
                {
                    for(int k=0;k<v[order[j]].size();k++)
                        t.push_back(v[order[j]][k]);
                }
                else
                {
                    for(int k=v[order[j]].size()-1;k>=0;k--)
                        t.push_back(v[order[j]][k]);
                }
            }
            memset(dp,0,sizeof(dp));
            for(int i=1;i<=n;i++)
            {
                for(int j=1;j<=n;j++)
                {
                    if(s[i]==t[j]) dp[i][j]=dp[i-1][j-1]+1;
                    else dp[i][j]=max(dp[i-1][j],dp[i][j-1]);
                }
            }
            ans=min(ans,n-dp[n][n]);
            t.clear();t.push_back(0);
        }
    }while(next_permutation(order,order+4));

    printf("%d
",ans);
    return 0;
}
View Code
原文地址:https://www.cnblogs.com/Kissheart/p/9749649.html