UVa 132 Another Chocolate Maniac(状压DP)

132. Another Chocolate Maniac

time limit per test: 0.25 sec.

memory limit per test: 4096 KB

Bob really LOVES chocolate. He thinks he never gets enough. Imagine his joy when his parents told him that they would buy him many rectangular chocolate pieces for his birthday. A piece of chocolate is a 2x1 or 1x2 rectangle.
Bob‘s parents also bought him a nice birthday cake, which can be imagined as a matrix having M rows and N columns. Some positions on the cake are occupied by candles, the others are empty. Bob‘s parents asked their son to
place as many chocolate pieces as he can on the empty squares on the cake, in such a manner that no two chocolate pieces overlap. However, he would like to keep the chocolate pieces to himself. That‘s why, he wants to place only a minimal amount of them on
the cake and keep the rest. In order not to make Mon and Dad suspicious, Bob wants to place the chocolate pieces in such a way, that no other piece may be placed on the cake (that is, there won‘t exist any two adjacent empty squares). Find the minimal number
of pieces which need to be placed on the cake, so that they do not overlap and no extra piece may be added.

Input

The first line of the input contains 2 integers: M (1<=M<=70) and N (1<=N<=7). Next, M lines will follow, each of them containing N characters,
describing the cake. The character on row and columnof the cake may be either a ‘*‘ (ASCII code 42), representing a candle, or a ‘.‘ (ASCII
code 46), representing an empty square.

Output

You should output one integer: the minimal amount of pieces of chocolate which need to be placed on the cake.

Sample Input

5 5
.*..*
*....
..**.
**.*.
.**..

Sample Output

4
 

思路 :dp[ i ][ s1 ][ s2 ] 表示第 i -1 行状态为s2,第 i 行状态为s2的方案数。然后就是dfs枚举状态。

dfs(p , s1 , s2 , s3 , cnt )(假设当前枚举的是第 i 行)p为当前枚举的列号 ,s1为i-2行的状态 ,

s2为i-1的状态,s3为i行的状态,cnt为放置的数目。

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int B[8]= {1,2,4,8,16,32,64,128};
const int inf=1<<30;
const int maxn=1<<8;
const int N=75;

int dp[2][maxn][maxn],a[N],cur,len,n,m,tmp,now;
char ch[10];

void input()
{
    scanf("%d %d",&n,&m);
    for(int i=1; i<=n; i++)
    {
        scanf("%s",ch);
        for(int j=0; j<m; j++)
        {
            a[i]<<=1;
            if(ch[j]=='*')  a[i]+=1;
        }
    }
}

void initial()
{
    cur=0;
    len=1<<m;
    for(int i=0; i<2; i++)
        for(int j=0; j<maxn; j++)
            for(int k=0; k<maxn; k++)
                dp[i][j][k]=inf;
    dp[cur][len-1][a[1]]=0;
}

void dfs(int p,int s1,int s2,int s3,int cnt)
{
    if(p>0 && !(s1 & B[p-1]) && !(s2 & B[p-1]))   return ;
    if(p>1 && !(s2 & B[p-1]) && !(s2 & B[p-2]))   return ;
    if(p>=m)
    {
         dp[cur][s2][s3]=min(dp[cur][s2][s3],dp[cur^1][tmp][now]+cnt);
         return ;
    }
    dfs(p+1,s1,s2,s3,cnt);
    if(p<m-1 && !(s2 & B[p]) && !(s2 & B[p+1]))  dfs(p+1,s1,s2|B[p]|B[p+1],s3,cnt+1);
    if(!(s2 & B[p]) && !(s3 & B[p]))    dfs(p+1,s1,s2|B[p],s3|B[p],cnt+1);
}

void solve()
{
    for(int i=1; i<=n; i++)
    {
        cur^=1;
        for(int j=0; j<len; j++)
            for(int k=0; k<len; k++)
                if(dp[cur^1][j][k]<inf)
                {
                    tmp=j;
                    now=k;
                    dfs(0,j,k,a[i+1],0);
                }
        for(int j=0; j<len; j++)
            for(int k=0; k<len; k++)
                dp[cur^1][j][k]=inf;
    }
    int ans=inf;
    for(int i=0; i<len; i++)  ans=min(ans,dp[cur][i][0]);
    printf("%d\n",ans);
}

int main()
{
    input();
    initial();
    solve();
    return 0;
}
时间: 2024-10-25 19:24:10

UVa 132 Another Chocolate Maniac(状压DP)的相关文章

UVA 10817 Headmaster&#39;s Headache 状压DP

记录两个状态S1,S2分别记录哪些课程被1个人教过或2个人教过,然后记忆化搜索 UVA - 10817 Headmaster's Headache Time Limit: 3000MS   Memory Limit: Unknown   64bit IO Format: %lld & %llu Submit Status Description Problem D: Headmaster's Headache Time limit: 2 seconds The headmaster of Spr

uva 11825 Hackers&#39; Crackdown (状压dp,子集枚举)

题目链接:uva 11825 题意: 你是一个黑客,侵入了n台计算机(每台计算机有相同的n种服务),对每台计算机,你可以选择终止一项服务,则他与其相邻的这项服务都终止.你的目标是让更多的服务瘫痪(没有计算机有该项服务). 思路:(见大白70页,我的方程与大白不同) 把n个集合P1.P2.Pn分成尽量多的组,使得每组中所有集合的并集等于全集,这里的集合Pi是计算机i及其相邻计算机的集合,用cover[i]表示若干Pi的集合S中所有集合的并集,dp[s]表示子集s最多可以分成多少组,则 如果cove

UVa 1252 - Twenty Questions(状压DP)

链接: https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=3693 题意: 有n(n≤128)个物体,m(m≤11)个特征.每个物体用一个m位01串表示,表示每个特征是具备还是不具备.我在心里想一个物体(一定是这n个物体之一),由你来猜.你每次可以询问一个特征,然后我会告诉你:我心里的物体是否具备这个特征.当你确定答案之后,就把答案告诉我(告

UVa 1412 - Fund Management(状压DP + 预处理)

链接: https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=4158 题意: 你有c(0.01≤c≤1e8)美元现金,但没有股票.给你m(1≤m≤100)天时间和n(1≤n≤8)支股票供你买卖,要求最后一天结束后不持有任何股票,且剩余的钱最多.买股票不能赊账,只能用现金买.已知每只股票每天的价格(0.01-999.99.单位是美元/股)与参数s

uva 11825 Hackers&amp;#39; Crackdown (状压dp,子集枚举)

题目链接:uva 11825 题意: 你是一个黑客,侵入了n台计算机(每台计算机有同样的n种服务),对每台计算机,你能够选择终止一项服务,则他与其相邻的这项服务都终止.你的目标是让很多其它的服务瘫痪(没有计算机有该项服务). 思路:(见大白70页,我的方程与大白不同) 把n个集合P1.P2.Pn分成尽量多的组,使得每组中全部集合的并集等于全集,这里的集合Pi是计算机i及其相邻计算机的集合,用cover[i]表示若干Pi的集合S中全部集合的并集,dp[s]表示子集s最多能够分成多少组,则 假设co

(状压dp)uva 10817 Headmaster&#39;s Headache

题目地址 1 #include <bits/stdc++.h> 2 typedef long long ll; 3 using namespace std; 4 const int MAX=1e5+5; 5 const int INF=1e9; 6 int s,m,n; 7 int cost[125]; 8 //char sta[MAX]; 9 string sta; 10 int able[125]; 11 int dp[125][1<<8][1<<8]; 12 in

【UVa】Headmaster&#39;s Headache(状压dp)

http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=1758 晕....状压没考虑循环方向然后错了好久.. 这点要注意...(其实就是01背包变成了完全背包QAQ 我们将课程拆成两个点,然后状压 那么答案就是(1<<(s<<1))-1 转移就不说了,,,,,太简单.. #include <cstdio> #in

UVA - 10817 Headmaster&#39;s Headache (状压dp+记忆化搜索)

题意:有M个已聘教师,N个候选老师,S个科目,已知每个老师的雇佣费和可教科目,已聘老师必须雇佣,要求每个科目至少两个老师教的情况下,最少的雇佣费用. 分析: 1.为让雇佣费尽可能少,雇佣的老师应教他所能教的所有科目. 2.已聘老师必须选,候选老师可选可不选. 3.dfs(cur, subject1, subject2)---求出在当前已选cur个老师,有一个老师教的科目状态为 subject1,有两个及以上老师教的科目状态为 subject2的情况下,最少的雇佣费用. dp[cur][subje

UVa 10817 (状压DP + 记忆化搜索) Headmaster&#39;s Headache

题意: 一共有s(s ≤ 8)门课程,有m个在职教师,n个求职教师. 每个教师有各自的工资要求,还有他能教授的课程,可以是一门或者多门. 要求在职教师不能辞退,问如何录用应聘者,才能使得每门课只少有两个老师教而且使得总工资最少. 分析: 因为s很小,所以可以用状态压缩. dp(i, s1, s2)表示考虑了前i个人,有一个人教的课程的集合为s1,至少有两个人教的集合为s2. 在递归的过程中,还有个参数s0,表示还没有人教的科目的集合. 其中m0, m1, s0, s1, s2的计算用到位运算,还