• 【CF1238E】Keyboard Purchase(状压DP,贡献)


    题意:有m种小写字符,给定一个长为n的序列,定义编辑距离为序列中相邻两个字母位置差的绝对值之和,其中字母位置是一个1到m的排列

    安排一种方案,求编辑距离最小

    n<=1e5,m<=20

    思路:刚开始不会算贡献,觉得一定要把具体的排列搞出来才能做

    其实pos[s[i-1]]和pos[s[i]]之差可以看成字符s[i-1]和字符s[i]被选择的时间的差

    也就是说只有一个没有被选,另一个被选的情况下每次都会累计这样的字母对数的贡献

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 typedef long long ll;
     4 typedef unsigned int uint;
     5 typedef unsigned long long ull;
     6 typedef pair<int,int> PII;
     7 typedef pair<ll,ll> Pll;
     8 typedef vector<int> VI;
     9 typedef vector<PII> VII;
    10 //typedef pair<ll,ll>P;
    11 #define N  200010
    12 #define M  200010
    13 #define fi first
    14 #define se second
    15 #define MP make_pair
    16 #define pb push_back
    17 #define pi acos(-1)
    18 #define mem(a,b) memset(a,b,sizeof(a))
    19 #define rep(i,a,b) for(int i=(int)a;i<=(int)b;i++)
    20 #define per(i,a,b) for(int i=(int)a;i>=(int)b;i--)
    21 #define lowbit(x) x&(-x)
    22 #define Rand (rand()*(1<<16)+rand())
    23 #define id(x) ((x)<=B?(x):m-n/(x)+1)
    24 #define ls p<<1
    25 #define rs p<<1|1
    26 
    27 const int MOD=1e9+7,inv2=(MOD+1)/2;
    28       double eps=1e-4;
    29       int INF=1e9;
    30       int inf=0x7fffffff;
    31       int dx[4]={-1,1,0,0};
    32       int dy[4]={0,0,-1,1};
    33 
    34       char s[N];
    35       int dp[1<<20],f[21][21];
    36 
    37 int read()
    38 {
    39    int v=0,f=1;
    40    char c=getchar();
    41    while(c<48||57<c) {if(c=='-') f=-1; c=getchar();}
    42    while(48<=c&&c<=57) v=(v<<3)+v+v+c-48,c=getchar();
    43    return v*f;
    44 }
    45 
    46 int main()
    47 {
    48     int n=read(),m=read();
    49     int S=(1<<m)-1;
    50     scanf("%s",s+1);
    51     rep(i,2,n)
    52     {
    53         int x=s[i-1]-'a',y=s[i]-'a';
    54         f[x][y]++;
    55         f[y][x]++;
    56     }
    57     rep(i,0,S) dp[i]=INF;
    58     dp[0]=0;
    59     rep(sta,0,S-1)
    60     {
    61         int t=0;
    62         rep(i,0,m-1)
    63         {
    64             if(sta>>i&1) continue;
    65             rep(j,0,m-1)
    66              if(sta>>j&1) t+=f[i][j];
    67         }
    68 
    69         rep(i,0,m-1)
    70         {
    71             if(sta>>i&1) continue;
    72             dp[sta+(1<<i)]=min(dp[sta+(1<<i)],dp[sta]+t);
    73         }
    74     }
    75     printf("%d
    ",dp[S]);
    76     return 0;
    77 }
  • 相关阅读:
    python简单文件服务器
    Qt5WebSockets
    cartographer ros 配置项
    ubuntu18.04 evo 测评工具安装
    ubuntu18.04 orb_slam2安装记录
    clonezilla使用说明
    会计报名
    将博客搬至CSDN
    JS--微信浏览器复制到剪贴板实现
    Python--Django学习笔记2
  • 原文地址:https://www.cnblogs.com/myx12345/p/11642329.html
Copyright © 2020-2023  润新知