求助WA0
查看原帖
求助WA0
1071494
unDefinedFuture楼主2024/6/8 15:04
// 2556. Uddered but not Herd
#include<cstdio>
#include<string>
#include<iostream>
#include<vector>
#include<map>
using namespace std;
int main()
{
    string inp; // 输入串
    cin>>inp;
    vector<vector<int> > c; // 相邻字母出现的次数
    vector<int> f; // 状压DP
    map<char,int> letpair; // 离散化,字母与离散后编号的pair
    
    // 对存在的字母进行标记
    for(int i=0;i<inp.length();i++)
    {
        letpair[inp[i]]=1;
    }
    // 离散化编号(利用map的自动排序)
    int i = 0, numofnum=0;
    for(auto iter=letpair.begin();iter!=letpair.end();iter++,i++)
    {
        iter->second=i;
        numofnum++;
    }
    
    // 动态数组resize
    f.resize((1<<numofnum)+5);
    c.resize(numofnum+5,vector<int>(numofnum+5));

    // 预处理c数组(相邻字母出现的次数)
    for(int i=0;i<inp.length()-1;i++)
    {
        c[letpair[inp[i]]][letpair[inp[i+1]]]++;
    }
    
    // 状压DP,status=状压后的选择情况(01串状压)
    for(int status=0;status<(1<<numofnum);status++)
    {
        // x=当前选的字母,在status中必须已选
        for(int x=0;x<numofnum;x++)
        {
            if((status&(1<<x))==0)continue; // 非已选,直接跳过
            int tempf = f[status-(1<<x)];
            // y=前面的字母,用于检测顺序,在status中必须已选
            for(int y=0;y<numofnum;y++)
            {
                if((status&(1<<y))==0)continue; // 非已选,直接跳过
                // 累加 tempf = f[status-(1<<x)] + sum(c[x][y])
                //           (不选x的情况下的status)
                tempf+=c[x][y];
            }
            // 对f[st-x]+sum(c[x][y])取最小值
            f[status]=min(f[status],tempf);
        }
    }
    printf("%d",f[(1<<numofnum)-1]);
    return 0;
}

样例输出0

2024/6/8 15:04
加载中...