【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\n",dp[S]);
76     return 0;
77 }

 

posted on 2019-10-09 15:56  myx12345  阅读(485)  评论(0编辑  收藏  举报

导航