zoukankan      html  css  js  c++  java
  • 【计蒜客习题】灌溉机器人

    问题描述


    农田灌溉是一项十分费体力的农活,特别是大型的农田。蒜头君想为农民伯伯们减轻农作负担,最近在研究一款高科技——灌溉机器人。它可以在远程电脑控制下,给农田里的作物进行灌溉。
    现在有一片 N 行 M 列的农田。农田的土壤有两种类型:类型 HH 和类型 PP,每一个格子上的土壤类型相同。其中类型 P 的土壤硬度较大,可以用来布置灌溉机器人,但是一个格子上只能布置一台。类型 H 的土壤不能布置灌溉机器人。一台灌溉机器人的灌溉区域如下图所示:

    黄色表示灌溉机器人布置的格子,红色表示其灌溉区域,即四个方向上各外扩展两个格子。
    蒜头君想在农田上尽可能多布置一些灌溉机器人,但是任意一台机器人不能在任意一台机器人的灌溉区域里,否则机器容易进水出故障。现在已知农田每个格子的土壤类型,请你来帮蒜头君计算一下,蒜头君最多能布置多少台灌溉机器人。


    输入格式


    输入第一行输入两个正整数N,M(N≤100,M≤10),表示农田的行和列。
    接下来输入 N 行,每行输入连续的 M 个字符(P或者H),中间没有空格。表示农田每个格子上的土壤类型。


    输出格式


    输出一行,输出一个整数,表示最多能摆放的灌溉机器人的数量

    样例输入

    3 4
    PHPP
    PHPP
    PHHP

    样例输出

    3


    呃呃,一道状压DP入门题。

    没什么好说的,注意先预处理一下,发现若要满足同一行不冲突,情况最多有60种。定义dp[i][j][k]表示处理到第i行,当前行选择方案为j,上一行选择方案为k时最多的摆放数量,这样就可以保证只需知道当前行的dp和上一行的dp就可以知道对当前行选择方案有影响的上一行和上上一行,转移方程显然是dp[i][j][k]=max{dp[i-1][k][l]+count(j)},count返回某一方案的机器人数量。再就是冲突时的判断需要写好。

     1 #include<cstdio>
     2 inline int max(int a,int b) {return a>b?a:b;}
     3 const int maxn=105,maxm=15;
     4 //经预先验证,满足同一行不冲突的情况最多有60种
     5 int n,m,map[maxn],state[65],cnt,dp[maxn][65][65],ans;
     6 bool judge1(int x) {
     7     return (x&(x>>1))==0&&(x&(x>>2))==0;
     8 }
     9 bool judge2(int i,int j) {
    10     return (j|map[i])==map[i];
    11 }
    12 bool judge3(int x,int y) {
    13     return (x&y)==0;
    14 }
    15 int count(int i) {
    16     int c=0;
    17     while(i) {
    18         if(i&1) ++c;
    19         i>>=1;
    20     }
    21     return c;
    22 }
    23 int main() {
    24     scanf("%d%d",&n,&m);
    25     for(int i=1;i<=n;++i) {
    26         int si=0;char c;
    27         for(int j=0;j<m;++j) {
    28             while((c=getchar())=='
    '||c==' '||c=='
    ');
    29             if(c=='P') si|=(1<<j);
    30         }
    31         map[i]=si;
    32     }
    33     for(int i=0;i<(1<<m);++i) if(judge1(i)) state[++cnt]=i;
    34     for(int i=1;i<=cnt;++i) if(judge2(1,state[i])) {
    35         int cnt_i=count(state[i]);
    36         for(int j=1;j<=cnt;++j) dp[1][i][j]=cnt_i;
    37     }
    38     for(int i=2;i<=n;++i)
    39         for(int j=1;j<=cnt;++j) if(judge2(i,state[j])) {
    40             int cnt_j=count(state[j]);
    41             for(int k=1;k<=cnt;++k) if(judge2(i-1,state[k])&&judge3(state[j],state[k]))
    42                 for(int l=1;l<=cnt;++l)
    43                     if(judge2(i-2,state[l])&&judge3(state[k],state[l])&&judge3(state[j],state[l]))
    44                         dp[i][j][k]=max(dp[i][j][k],dp[i-1][k][l]+cnt_j);
    45         }
    46     for(int i=1;i<=cnt;++i)
    47         for(int j=1;j<=cnt;++j) ans=max(ans,dp[n][i][j]);
    48     printf("%d",ans);
    49     return 0;
    50 }
    AC代码
  • 相关阅读:
    Codeforces 1316B String Modification
    Codeforces 1305C Kuroni and Impossible Calculation
    Codeforces 1305B Kuroni and Simple Strings
    Codeforces 1321D Navigation System
    Codeforces 1321C Remove Adjacent
    Codeforces 1321B Journey Planning
    Operating systems Chapter 6
    Operating systems Chapter 5
    Abandoned country HDU
    Computer HDU
  • 原文地址:https://www.cnblogs.com/Mr94Kevin/p/9635865.html
Copyright © 2011-2022 走看看