码迷,mamicode.com
首页 > 其他好文 > 详细

状态压缩DP入门

时间:2019-08-11 21:29:02      阅读:335      评论:0      收藏:0      [点我收藏+]

标签:入门   限制   for   blank   its   printf   struct   problem   通过   

简介

状态压缩DP是将一连串状态压缩成为一个P进制(P通常为2)数,并由此达到压缩的目的

例题

P1879 [USACO06NOV]玉米田Corn Fields

因为只和之前的一行有关系,就可以通过状压先找出这一行中合法的状态,再和上一行的进行转移

Code

 

#include<bits/stdc++.h>
using namespace std;
const int mod=1e8;
int n,m,f[20][5001];
struct state{int c[5005],num;}a[20];
void change(int k,int t){
    for(int i=0;i<(1<<n);i++)
     if(!(i&(i<<1))&&!(i&(i>>1))&&!(i&t))
      a[k].c[++a[k].num]=i;
}
int main(){
    scanf("%d%d",&m,&n);
    for(int i=1;i<=m;i++){
        int t=0;
        for(int j=1,x;j<=n;j++)
         scanf("%d",&x),t=(t<<1)+1-x;
        change(i,t);
    }
    for(int i=1;i<=a[1].num;i++)f[1][i]=1;
    for(int i=2;i<=m;i++)
     for(int j=1;j<=a[i].num;j++)
      for(int k=1;k<=a[i-1].num;k++)
       if(!(a[i].c[j]&a[i-1].c[k]))
        f[i][j]=(f[i-1][k]+f[i][j])%mod;
    int ans=0;
    for(int i=1;i<=a[m].num;i++)
     ans=(ans+f[m][i])%mod;
    printf("%d\n",ans); 
}

 

P1896 SCOI2005互不侵犯

这题还要简单一些,不用考虑限制

#include<bits/stdc++.h>
using namespace std;
int n,k;
long long f[15][155][155];
int num[155],s[155];
int main(){
    scanf("%d%d",&n,&k);
    for(int i=0;i<(1<<n);i++){
        if(i&(i<<1))continue;
        s[++s[0]]=i;
        for(int j=0;j<n;j++)if(i&(1<<j))++num[s[0]];
    }
    f[0][1][0]=1;
    for(int i=1;i<=n;i++)
     for(int j=1;j<=s[0];j++)
      for(int kk=0;kk<=k;kk++)
       if(kk>=num[j])
        for(int t=1;t<=s[0];t++)
         if(!(s[t]&s[j])&&!(s[t]&(s[j]>>1))&&!(s[t]&(s[j]<<1)))
          f[i][j][kk]+=f[i-1][t][kk-num[j]];
    long long ans=0;
    for(int i=1;i<=s[0];i++)ans+=f[n][i][k];
    printf("%lld\n",ans);
}

 

状态压缩DP入门

标签:入门   限制   for   blank   its   printf   struct   problem   通过   

原文地址:https://www.cnblogs.com/coder-cjh/p/11336451.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!