Robert is clipping his fingernails. But the nail clipper is old and the edge of the nail clipper is potholed.

The nail clipper's edge is N millimeters wide. And we use N characters('.' or '*') to represent the potholed nail clipper. '.' represents 1 bad millimeter edge, and '*' represents 1 good millimeter edge.(eg. "*****" is a 5 millimeters nail clipper with the whole edge good. "***..." is a 6 millimeters nail clipper with half of its edge good and half of its edge bad.)

Notice Robert can turn over the clipper. Turning over a "**...*"-nail clipper will make a "*...**"-nail clipper.

One-millimeter good edge will cut down Robert's one-millimeter fingernail. But bad one will not. It will keep the one-millimeter unclipped.

Robert's fingernail is M millimeters wide. How many times at least should Robert cut his fingernail?

Input

There will be multiple test cases(about 15). Please process to the end of input.

First line contains one integer N.(1≤N≤10)

Second line contains N characters only consists of '.' and '*'.

Third line contains one integer M.(1≤M≤20)

Output

One line for each case containing only one integer which is the least number of cuts. If Robert cannot clipper his fingernail then output -1.

Sample Input

8
****..**
4
6
*..***
7

Sample Output

1
2

Hint

We use '-' to present the fingernail.
For sample 1:
fingernail:	----
nail clipper:	****..**
Requires one cut.

For sample 2:
fingernail:			-------
nail clipper:			*..***
nail clipper turned over:	 ***..*
Requires two cuts.

这个题目对于我来说还是太难了,现在对dfs仅仅是知道贴上大牛代码一份,留作复习研究

解法一:

#include <stdio.h>
#include <math.h>
#include <string.h>
#include <algorithm>
using namespace std;

int n,m,right,left,minn;
];
];

void dfs(int fig[],int s,int flag,int step)
{
    ];
    if(step>=minn) return ;
    if(flag)
    {
        ; i<=; i++)
            tem[i] = fig[i];
        for(i = s,j = left; i<=m && j<=n; i++,j++)
        {
            if(!tem[i])
                tem[i] = clp[j];
        }
        for(i = s; i<=m; i++)
        {
            if(!tem[i])
            {
                s = i;
                break;
            }
        }
        )
        {
            if(step<minn)
            {
                minn = step;
            }
            return ;
        }
        dfs(tem,s,,step+);
        dfs(tem,s,,step+);
    }
    else
    {
        ; i<=; i++)
            tem[i] = fig[i];
        ; i++,j--)
        {
            if(!tem[i])
                tem[i] = clp[j];
        }
        for(i = s; i<=m; i++)
        {
            if(!tem[i])
            {
                s = i;
                break;
            }
        }
        )
        {
            if(step<minn)
            {
                minn = step;
            }
            return ;
        }
        dfs(tem,s,,step+);
        dfs(tem,s,,step+);
    }
}

int main()
{
    ];
    while(~scanf("%d",&n))
    {
        scanf("%s",str);
        memset(clp,,sizeof(clp));
        ; i<n; i++)
        {
            if(str[i] == '*')
                clp[i+] = ;
        }
        left = ;
        ; i<=n; i++)
            if(clp[i])
            {
                left = i;
                break;
            }
        ; i--)
            if(clp[i])
            {
                right = i;
                break;
            }
        scanf("%d",&m);
        )
        {
            printf("-1\n");
            continue;
        }
        minn = ;
        memset(fig,,sizeof(fig));
        dfs(fig,,,);
        dfs(fig,,,);
        printf("%d\n",minn);
    }

    ;
}

解法二:

首先把 (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还需要分正反情况考虑。

#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;

#define INF 0x3f3f3f3f
 << ];
],rev[];

int main() {

    int n,m,left,right;
    while(~scanf("%d%s%d",&n,s,&m))
    {
        ;i<n;i++)
            rev[i]=s[n-i-];
        left=; right=;
        ;i<n;i++)
        {
            left=left<<;  right=right<<;
            if(s[i]=='*')
                left|=;
            if(rev[i]=='*')
                right|=;
        }
        ;i<<<m;i++)
            dp[i]=INF;
        dp[(<<m)-]=;
        <<m)-;i>=;i--)
        {
            if(dp[i]==INF)//  由i 剪到 i&(~(left<<j)的状态  若 。。  说明这还没被剪过
                continue;
            ;j<m;j++)
            {
                dp[i&(~(left<<j))]=min(dp[i&(~(left<<j))],dp[i]+);
                dp[i&(~(left>>j))]=min(dp[i&(~(left>>j))],dp[i]+);
                dp[i&(~(right<<j))]=min(dp[i&(~(right<<j))],dp[i]+);
                dp[i&(~(right>>j))]=min(dp[i&(~(right>>j))],dp[i]+);
            }
        }
        ]<INF)
            printf(]);
        else printf("-1\n");
    }
    ;
}

ZOJ3675:Trim the Nails的更多相关文章

  1. ZOJ 3675 Trim the Nails

    http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=4918 DP+状态压缩. http://www.cnblogs.com/dgsr ...

  2. ZOJ 3675 Trim the Nails(bfs)

    Trim the Nails Time Limit: 2 Seconds      Memory Limit: 65536 KB Robert is clipping his fingernails. ...

  3. 2014 Super Training #6 G Trim the Nails --状态压缩+BFS

    原题: ZOJ 3675 http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3675 由m<=20可知,可用一个二进制数表 ...

  4. ZOJ Monthly, November 2012

    A.ZOJ 3666 Alice and Bob 组合博弈,SG函数应用 #include<vector> #include<cstdio> #include<cstri ...

  5. [PHP源码阅读]trim、rtrim、ltrim函数

    trim系列函数是用于去除字符串中首尾的空格或其他字符.ltrim函数只去除掉字符串首部的字符,rtrim函数只去除字符串尾部的字符. 我在github有对PHP源码更详细的注解.感兴趣的可以围观一下 ...

  6. php的empty(),trim(),strlen()方法

    如果empty()函数的参数是非空或非零的值,则empty()返回FALSE.换句话说,"".0."0".NULL.array().var$var:以及没有任何 ...

  7. ORACLE中的LTRIM、RTRIM和TRIM

    LTRIM.RTRIM和TRIM在ORACLE中的用法:1.LTRIM(C1,C2)其中C1和C2都可以字符串,例如C1是'Miss Liu',C2'MisL'等等.这是第一个和SQL SERVER不 ...

  8. mybatis : trim标签, “等于==”经验, CDATA标签 ,模糊查询CONCAT,LIKE

    一.My Batis trim标签有点类似于replace效果. trim 属性, prefix:前缀覆盖并增加其内容 suffix:后缀覆盖并增加其内容 prefixOverrides:前缀判断的条 ...

  9. IE8下String的Trim()方法失效的解决方案

    简洁方便 用jquery的trim()方法,$.trim(str)就可以了.

随机推荐

  1. css 的小细节,小总结

    CSS的一些零碎总结 1.CSS 伪元素用于向某些选择器设置特殊效果(用来当作一个东西的,跟一个元素差不多,但不是元素). ① :frist-line伪元素:用于向文本首行设置特殊样式,但是只能用于块 ...

  2. hdu 2063 过山车(二分图最佳匹配)

    经典的二分图最大匹配问题,因为匈牙利算法我还没有认真去看过,想先试试下网络流的做法,即对所有女生增加一个超级源,对所有男生增加一个超级汇,然后按照题意的匹配由女生向男生连一条边,跑一个最大流就是答案( ...

  3. Eclipse 设置文件的默认打开方式

    web开发中,我们在编辑JSP/xml的时候,会碰到一个非常郁闷的事,直接双击打开的JSP页面,当我们在编辑的时候会到处跳,这个我是深有体会,所以我们就用右击 open with,但是久而久之我们会感 ...

  4. Spring集成JPA提示Not an managed type

    在做Spring与JPA集成时,出现问题如下: Caused by: java.lang.IllegalArgumentException: Not an managed type: class co ...

  5. 阿里云+wordpress搭建个人博客网站

    [正文] 在阿里云上搭建使用个人博客主要分为以下几个步骤: 1.购买阿里云ECS主机 2.购买域名 3.申请备案 4.环境配置 5.安装wordpress 6.域名解析 声明一下,本人对服务器端的知识 ...

  6. Perl 语法 - 基础

    perl语言的核心是正则表达式,在文本处理上非常有优势,与python类似,但语法不同,perl的语法很灵活,用多了才会觉得好用. 常用知识点总结: perl语法类似于C语言(perl源于Unix), ...

  7. [转]Android 5.0——Material Design详解(动画篇)

    Material Design:Google推出的一个全新的设计语言,它的特点就是拟物扁平化. Material Design包含了很多内容,今天跟大家分享一下Material新增的动画: 在Andr ...

  8. Windows文本文件编码

    目录 1 ANSI编码    2 2 UTF16BE编码    2 3 UTF16LE编码    2 4 UTF-8编码    2 5 BOM    3 6 乱码    3 7 总结    5 如下图 ...

  9. FileReader本地预览图片

    <body> <p><label>请选择一个图像文件:</label><input type="file" id=" ...

  10. python实现微信打飞机游戏

    环境:Ubuntu 16.04 LTS Python 2.7.11 +  Pygame + Pycharm 代码: # -*- coding: UTF-8 -*- import pygame, ran ...