浅谈状压DP

浅谈状压DP

状压DP,是指通过一个01串来记录转移的状态,再通过DP的思想转移方程。

例:如共有五个节点,当前选择了第1、2、3号节点,则状态为

(00111)2 = (7) 10

由于计算机中的存储都采用二进制,我们可以通过位运算很方便的进行状态转移

注意:状压DP一般数据范围较小,多通过位运算进行转移,且较为简单。但一般需要预处理,需要十分细致,很锻炼码力。

例:JDOJ P1104 最佳挑水

题目传送门

一道状压DP裸题,我的做法是预处理出所有挑水方式的状态,并将矩阵存为DP数组的初始值。

#include<cstdio>
#include<cstring>
int n;
int dp[1<<19];
int sta[400],cnt=0;
int min(int x,int y)
{
   return x<y?x:y;
}
int main()
{
   scanf("%d",&n);
   memset(dp,0x3f,sizeof(dp));
   for(int i=0;i<n;i++)
  {
       int l = 1 << i ;
       for(int j=0;j<n;j++)
      {
           int r = 1 << j;
           int v;
           scanf("%d",&v);
           if(j==i) continue;
           sta[++cnt] = l + r;
           dp[l|r] = v ;
      }
  }
   dp[0] = 0;
  for(int i=1;i<=cnt;i++)
  {
      int s = sta[i];
      for(int j=0;j<=(1<<n)-1;j++)
      {
          if((s&j)==0)
          {
              dp[s|j] = min(dp[s|j],dp[s]+dp[j]);
          }
      }
  }
   printf("%d",dp[(1<<n)-1]);
}



posted @ 2020-10-12 22:32  岚默笙  阅读(188)  评论(0编辑  收藏  举报