zoukankan      html  css  js  c++  java
  • zoj 3675 剪指甲 状态压缩dp

    学习了博客  http://www.cnblogs.com/dgsrz/articles/2791363.html

    首先把 (1<<m)-1 作为指甲没剪时的初态(全是1),dp[x]保存的就是对于每个状态,需要剪的最少次数。
    当前状态x以二进制表示时,出现的1表示这一位置还留有指甲,0就是已剪去。而对于指甲钳,又可以将其以二进制表示,对于案例:****..**,不妨用11110011代替,1表示当前位置刀锋完好,0相反。于是对每一位分析:

    原来指甲情况 A 指甲钳刀锋 B 最终指甲情况 Y
    0 0 0
    0 1 0
    1 0 1
    1 1 0

    化简一下得到每一位上的关系:Y = A & ~B
    所以递推方程就是:dp[x & (~B)] = min(dp[x & (~B)], dp[x] + 1);
    问题是,指甲钳并不总是和指甲最左端对齐,所以还需要对指甲钳进行移动。反应在上式,就是对B进行左右各m次的移位操作。另外,指甲钳可以反着用,于是B还需要分正反情况考虑。

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <iostream>
     4 using namespace std;
     5 
     6 #define INF 0x3f3f3f3f
     7 int dp[1 << 20];
     8 char s[20],rev[20];
     9 
    10 int main() {
    11 
    12     int n,m,left,right;
    13     while(~scanf("%d%s%d",&n,s,&m))
    14     {
    15         for(int i=0;i<n;i++)
    16             rev[i]=s[n-i-1];
    17         left=0; right=0;
    18         for(int i=0;i<n;i++)
    19         {
    20             left=left<<1;  right=right<<1;
    21             if(s[i]=='*')
    22                 left|=1;
    23             if(rev[i]=='*')
    24                 right|=1;
    25         }
    26         for(int i=0;i<1<<m;i++)
    27             dp[i]=INF;
    28         dp[(1<<m)-1]=0;
    29         for(int i=(1<<m)-1;i>=0;i--)
    30         {
    31             if(dp[i]==INF)//  由i 剪到 i&(~(left<<j)的状态  若 。。  说明这还没被剪过
    32                 continue;
    33             for(int j=0;j<m;j++)
    34             {
    35                 dp[i&(~(left<<j))]=min(dp[i&(~(left<<j))],dp[i]+1);
    36                 dp[i&(~(left>>j))]=min(dp[i&(~(left>>j))],dp[i]+1);
    37                 dp[i&(~(right<<j))]=min(dp[i&(~(right<<j))],dp[i]+1);
    38                 dp[i&(~(right>>j))]=min(dp[i&(~(right>>j))],dp[i]+1);
    39             }
    40         }
    41         if(dp[0]<INF)
    42             printf("%d
    ",dp[0]);
    43         else printf("-1
    ");
    44     }
    45     return 0;
    46 }
  • 相关阅读:
    Binary Tree Postorder Traversal
    Insertion Sort List
    Unique Binary Search Trees
    Gas Station
    Path Sum II
    tkinter中鼠标与键盘事件(十五)
    tkinter中树状结构的建立(十四)
    tkinter中表格的建立(十三)
    tkinter中menu菜单控件(十二)
    tkinter中spinbox递增和递减控件(十)
  • 原文地址:https://www.cnblogs.com/assult/p/3722400.html
Copyright © 2011-2022 走看看