codeforces1238-div2

C

目前在h的高度,1~h每一个台阶要么处于out的状态,要么处于in的状态,问最少改变几个台阶的状态,使得能够从h的高度到0.
下降的唯一的方式,拉动lever,h-1的状态取反,下落的最大的高度不能超过2.

按照题目模拟其实就行了, 自己写的代码很挫。

D

仅有A,B组成的字符串,一个串是good串当且仅当每一个字符属于一个长度最小是2的串。
问有多少个good substring.
计算所有的非good串,然后总的方案数减去就可以了。

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<queue>
#include<cmath>
#include<map>
#include<stack>
#include<set>
#include<bitset>
 
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> pii;
#define pb(x) push_back(x)
#define cls(x, val) memset(x, val, sizeof(x))
#define fi first
#define se second
#define mp(x, y) make_pair(x, y)
#define inc(i, l, r) for(int i=l; i<=r; i++)
const int inf = 0x3f3f3f3f;
const int maxn = 2000+10;
string s;
 
int main(){
    ios::sync_with_stdio(false);
    ll ans = 0;
    int len;
    cin>>len;
    cin>>s;
    int pre = 0;
    for(int i=0; i<len; i++){
        if(i&&s[i]!=s[i-1]){
            ans += (i-pre);
            pre=i;
        }
        else if(i) if(pre) ans++;
    }
    cout<<1ll*len*(len-1)/2-ans<<endl;
 
    return 0;
}
 

E 状压dp

给一个字符串,然后要求给出一种线性排列的键盘,使得给定的方案的字符串从0->n的总的距离最短。
其中还有一种费用提前计算的思想。

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<queue>
#include<cmath>
#include<map>
#include<stack>
#include<set>
#include<bitset>

using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> pii;
#define pb(x) push_back(x)
#define cls(x, val) memset(x, val, sizeof(x))
#define fi first
#define se second
#define mp(x, y) make_pair(x, y)
#define inc(i, l, r) for(int i=l; i<=r; i++)
const int inf = 0x3f3f3f3f;
const int maxn = (1<<20)+10;
int dp[maxn];
int n, m;
string s;
int dis[21][21];



int main(){
    ios::sync_with_stdio(false);
    cin>>n>>m;
    cin>>s;
    cls(dis, 0);
    for(int i=1; i<s.length(); i++){
        int a = s[i-1]-'a';
        int b = s[i]-'a';
        dis[a][b]++, dis[b][a]++;
    }
    dp[0] = 0;
    for(int i=1; i<(1<<m); i++){
        dp[i] = inf;
        int tot = 0;
        for(int j=0; j<m; j++){
            for(int k=j+1; k<m; k++){
                //有点费用提前计算的思想,未加入到集合中的元素的距离全部都加上,0->1, 1->0
                if((i>>j&1)^(i>>k&1)) tot += dis[j][k];
            }
        }
        for(int j=0; j<m; j++) if(i>>j&1)dp[i] = min(dp[i], dp[i^(1<<j)]+tot);
    }
    cout<<dp[(1<<m)-1]<<endl;

    return 0;
}

posted @ 2019-10-09 10:35  babydragon  阅读(188)  评论(0编辑  收藏  举报