0915 反思

时间:2019-09-16
本文章向大家介绍0915 反思,主要包括0915 反思使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

这场比赛还是打的很迷
A题我居然没看出来是状态压缩
B题本来是一道DP题 我脑抽 写了一发最短路..... 然后空间就超了
C题打暴力只有30分 没有想到换根操作
A

N<=16!!!
zz 一味地打表 然后居然认为这是一个求逆序对的题目...
首先一看范围 状态压缩 这很显然
\(F[I]\)表示把集合i 里面的元素合并的最小步数
考虑转移
注意到 当集合为回文串的时候 只需要多操作一步
所以 \(F[I]=MIN(F[I\)^\(S]+1,F[I])\)
预处理回文串
CODE:

//
#include<bits/stdc++.h>
using namespace std;
#define maxnn 100000
int mark[1<<21];
int all,n;
int f[1<<21];
char s[maxnn];
int main() {
    scanf("%s",s+1);
    n=strlen(s+1);
    int all=(1<<n)-1;
    for(int i=0; i<=all; i++) {
        int l=0,r=0;
        for(int k=1; k<=n; k++) {
            if((1<<k-1)&i) {
                l=k;
                break;
            }
        }
        for(int k=n; k>=1; k--) {
            if((1<<k-1)&i) {
                r=k;
                break;
            }
        }
        if(s[l]!=s[r]) {
            mark[i]=0;
            continue;
        }
        if((l==0)||(r==0)) continue;
        while(l<=r) {
            while((!(i&(1<<l-1)))) l++;
            while((!(i&(1<<r-1)))) r--;
            if(s[l]!=s[r]) {
                mark[i]=0;
                f[i]=0;
                break;
            }
            l++,r--; 
        f[i]=1;
        mark[i]=1;
        }
       
    }
  
    for(int i=0; i<=all; i++) {
        for(int k=i; k; k=(k-1)&i) {
            if(mark[k]==1) {
                if(f[i]==0)
                    f[i]=f[i^k]+1;
                else
                {
                    f[i]=min(f[i],f[i^k]+1);
                 
                }
            }
        }
   
    }
  
    cout<<f[all];
}

原文地址:https://www.cnblogs.com/OIEREDSION/p/11528597.html