题解:P13792 [SWERC 2023] Card game

· · 题解

题目链接

题目大意

有五种花色的牌,分别为银色 S,白色 W,绿色 E,红色 R,还有一个更加高级的青色 C。每种花色有 N 张牌,我们的手里也有 N 张牌。现在我们需要让同一花色的所有牌按递增顺序相邻排列,并且青色牌要放在末尾(同样按递增顺序排列)。

思路分析

int N; int pos[4]; vector<pair<int,int>> card; vector<int> a={0,1,2,3};//记录四种颜色的位置,转换为优先值
int max_len=INT_MIN;

int get_len() { vector<pair<int,int>> dp; //遍历每一张卡片 for(int i=0;i<card.size();i++) { int color=card[i].first;//当前卡片的颜色
int num=card[i].second;//当前卡片的编号

    //计算当前卡片对应的优先级p:
    //若为'C',p固定为4,其他颜色则使用其在当前排列中的位置pos[color]
    int p=(color == 4) ? 4 : pos[color];

    int l=0,r=dp.size();
    while(l < r)
    {
        int mid=l+(r-l)/2;
        if(dp[mid].first > p || (dp[mid].first == p && dp[mid].second >= num))
            r=mid;
        else
            l=mid+1;
    }
    if(l == dp.size())
        dp.emplace_back(p,num);
    else
        dp[l]={p,num};
}
//返回在当前颜色排列下上升子序列的长度 
return dp.size();

}

int main() { ios::sync_with_stdio(false); cin.tie(nullptr);

cin >> N;

for(int i=0;i<N;i++)
{
    string s;
    cin >> s;
    int color;
    if(s[0] == 'S')
        color=0;
    else if(s[0] == 'W')
        color=1;
    else if(s[0] == 'E')
        color=2;
    else if(s[0] == 'R')
        color=3;
    else//'C'
        color=4;
    int num=stoi(s.substr(1));
    card.emplace_back(color,num);
}

//处理初始排列 
for(int i=0;i<4;i++)
    pos[a[i]]=i;
max_len=max(max_len,get_len());

//处理剩余排列 
while(next_permutation(a.begin(),a.end()))
{
    for(int i=0;i<4;i++)
        pos[a[i]]=i;
    max_len=max(max_len,get_len());
}

cout << N-max_len;

return 0;

}