• power oj 1557种树[二进制状压DP]


    题目链接【https://www.oj.swust.edu.cn/problem/show/1557】

    题意:中文题目。

    题解:用0,1表示某个位置是否种了树,先算出同一行的有效状态的总数,即开两个1状态不能相邻的状态。

    枚举每一行的状态然后根据行一行的状态判断改状态是否有效,然后对最后一行的所有有效状态求最大值即可。

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long LL;
    int bas[105], k[150], N[150];
    int dp[105][150];
    char s[105];
    int n, m, nu;
    void init()
    {
        memset(dp, 0, sizeof(dp));
        memset(bas, 0, sizeof(bas));
        memset(N, 0, sizeof(N));
        nu = 0;
    }
    int main ()
    {
        while(~scanf("%d%d", &n, &m))
        {
            if(n == 0 && m == 0)
                break;
            init();
            for(int i = 1; i <= n; i++)
            {
                scanf("%s", s);
                for(int j = 0; j < m; j++)
                {
                    if(s[j] == '*')
                        bas[i] += (1 << j);
                }
            }
            for(int i = 0; i <= (1 << m) - 1; i++)
            {
                if((!(i & (i << 1))) && (!(i & (i >> 1))))//有效状态
                {
                    k[nu] = i;
                    int t = i;
                    while(t)
                    {
                        if(t & 1) N[nu]++;
                        t >>= 1;
                    }
                    nu++;
                }
            }
            for(int j = 0; j < nu; j++)
            {
                if(!(k[j]&bas[1]))
                    dp[1][j] = N[j];
            }
            for(int i = 2; i <= n; i++)
            {
                for(int j = 0 ; j < nu; j++)//i行
                {
                    if(k[j]&bas[i]) continue;//判断第i行
                    for(int t = 0; t < nu; t++)
                    {
                        if(k[t]&bas[i - 1]) continue; //判断第i-1行
                        if((k[t]&k[j]) || (k[t] & (k[j] << 1)) || (k[t] & (k[j] >> 1))) continue;
                        dp[i][j] = max(dp[i][j], dp[i - 1][t] + N[j]);
                    }
                }
            }
            int ans = 0;
            for(int i = 0; i < nu; i++)
                ans = max(dp[n][i], ans);
            printf("%d
    ", ans);
        }
        return 0;
    }
    想的太多,做的太少。
  • 相关阅读:
    2020软件工程作业04
    2020软件工程作业03
    2020软件工程作业02
    2020软件工程作业01
    Linux操作系统分析-课程学习总结报告
    结合中断上下文切换和进程上下文切换分析Linux内核的一般执行过程
    深入理解系统调用
    基于mykernel 2.0编写一个操作系统内核
    交互式多媒体图书平台的设计与实现
    码农放入自我修养之必备技能学习笔记
  • 原文地址:https://www.cnblogs.com/pealicx/p/6234699.html
Copyright © 2020-2023  润新知