zoukankan      html  css  js  c++  java
  • [swustoj 183] 种树

    种树(0183)

    问题描述

    Aconly有一块矩形的地,因为这块地里有很多石头,耕作很不方便,所以他打算在这块地上种一些果树。这块地用一个只含‘#’和‘*’的N*M的矩阵来表示,‘#’表示泥土,‘*’表示石头。当然有石头的地方是不能种树的,而且任意两棵树之间不能离得太近,表现在矩阵中就是不能上、下、左、右、左上、右上、左下、右下八个方向相邻。你的任务就是帮助Aconly算出这块地最多可以种多少棵树。

    输入

    有多组测试数据。每组测试数据以两个整数N和M开头,随后有N行只含‘#’和‘*’的字符,每行M个。 (1<=N<=100, 1<=M<=10)当M=N=0时表示输入结束。

    输出

    每组数据输出一个整数,表示Aconly最多可以在这块地里种多少棵树。每组输出数据占一行。

    样例输入

    5 4
    ####
    **#*
    ##*#
    ####
    ##*#
    0 0

    样例输出

    6

    简单状压DP、代码还可以继续优化

    #include <iostream>
    #include <cstring>
    #include <algorithm>
    #include <cstdio>
    #include <cmath>
    using namespace std;
    #define ll long long
    #define int2 unsigned int
    #define MOD (1<<32)
    #define INF 0x3f3f3f3f
    #define N 1024
    
    int n,m;
    int a[N];
    int dp[N][N];   //dp[i][j]表示第i行状态为j时的最大种树棵数
    char mpt[N][N];
    
    bool judge(int row,int sta)
    {
        if((a[row]&sta)!=sta) return 0;
        if(sta&(sta<<1)) return 0;
        return 1;
    }
    bool judge2(int r1,int r2)
    {
        if(r1&r2) return 0;
        if((r1<<1)&r2 || (r1>>1)&r2) return 0;
        return 1;
    }
    int cal1(int n)
    {
        int ret=0;
        while(n){
            ret+=n%2;
            n>>=1;
        }
        return ret;
    }
    void solve()
    {
        int i,j,k;
        int MAX=1<<m;
        dp[0][0]=0;
        for(i=1;i<=n;i++){
            for(j=0;j<MAX;j++){
                if(!judge(i,j)) continue;
                for(k=0;k<MAX;k++){
                    if(!judge2(j,k)) continue;
                    dp[i][j]=max(dp[i][j],dp[i-1][k]+cal1(j));
                }
            }
        }
        int ans=0;
        for(i=n,j=0;j<MAX;j++) ans=max(ans,dp[i][j]);
        printf("%d
    ",ans);
    }
    int main()
    {
        while(scanf("%d%d",&n,&m),n||m)
        {
            memset(a,0,sizeof(a));
            memset(dp,0,sizeof(dp));
            for(int i=1;i<=n;i++){
                for(int j=1;j<=m;j++){
                    char ch;
                    scanf(" %c",&ch);
                    if(ch=='#') a[i]=(a[i]<<1)+1;
                    else a[i]=(a[i]<<1);
                }
            }
            solve();
        }
        return 0;
    }
  • 相关阅读:
    系统消息系统公告数据建模
    Chrome部分站点无法启用Flash问题
    使用netstat命令查看端口的使用情况
    Jave基本数据类型
    Mac下Tomcat安装&配置&80默认端口设置
    React学习及实例开发(一)——开始(转载)
    jQuery、layer实现弹出层的打开、关闭功能实例详解
    jQuery获取节点和子节点文本的方法
    jquery 获取$("#id").text()里面的值 需要进行去空格去换行符操作
    ES6数组新增的几个方法
  • 原文地址:https://www.cnblogs.com/hate13/p/4570125.html
Copyright © 2011-2022 走看看