POJ Corn Fields 状态压缩DP基础题
题目链接:http://poj.org/problem?id=3254
题目大意(名称什么的可能不一样,不过表达的意思还是一样的):
种玉米
王小二从小学一年级到现在每次考试都是班级倒数第一名,他的爸爸王大强觉得读书对于王小二来说应该是没有出路了,于是决定让王小二继承自己的衣钵,从事一份非常有前途的工作——种玉米。王大强是一位富有的农场主,他拥有一块 M*N 平方米的矩形田地专门用来种玉米(1<=M,N<=12)。这个玉米地被分成了 M*N 个,每个格子是一个大小为1平方米的格子。这块玉米地中有一些格子因为还没有开垦,所以上面长满了岩石,所以这些格子是不适合种玉米的。相邻的格子也是不能同时种玉米的,因为如果这么做了的话,两个格子区域的玉米因为相互抢夺土壤里面的资源结果会都长不好。
虽然王小二的成绩不好,但是他是一个喜欢思考的人,他想要知道一共有多少种可行的方式来种玉米。
输入
第一行包括两个正数M和N。
接下来M行每行包含N个整数,数字1表示这个格子是适合种玉米的,数字0表示这个格子不适合种玉米。
输出
输出一个整数,表示种玉米的方案数。(除 100,000,000 取模)
样例输入
2 3
1 1 1
0 1 0
样例输出
9
题目分析:这道题目可以用状态压缩DP来处理。
dp[i][j] 表示第i行的状态取为j的时候的方案总数,那么这个j的状态是什么意思呢?
j虽然是一个整数,但是它其实表示的是一行的所有二进制状态。
比如,如果我们某一行的三个格子分别是:种、不种、种,我们用 1 表示“种”,用 0 表示“不种”, 那么这一行其实可以表示成 1,0,1 对应的二进制数就是 101 ,这个数对应的十进制的数就是 1*4+0*2+1*1 = 5,
我们还要过滤一下每一行的状态,第i行的状态j成立的条件是:
- j对应的状态上没有在有岩石的格子上种玉米;
 - j对应的状态不会有连续的两列上种玉米。
 
这两点我在代码上面有比较明确的体现。
然后我们就可以得到状态转移方程:
dp[i][j] = 1, 其中i==0(第0行),j是第i行的合理状态(满足上面提到的两个条件)
dp[i][j] = sum(dp[i-1][k]),其中i>0,j是第i行的合理状态,k是第i-1行的所有合理状态的集合,并且j和k状态满足关系式:j&k==0,对应的字面意思就是不存在连续的两行同一列都种着玉米
最后的结果就是 sum(dp[M-1][j]),其中j对应第M-1的所有合理状态。
代码:
#include <iostream>
#include <vector>
#include <cstring>
using namespace std;
const int maxn = 13;
const int MOD = 100000000;
int M, N, dp[maxn][1<<maxn], g[maxn][maxn];
vector<int> states[maxn];
void test() {
    for (int i = 0; i < M; i ++) {
        cout << (i+1) << "(" << states[i].size() << "): ";
        int sz = states[i].size();
        for (int j = 0; j < sz; j ++) {
            if (j) cout << ",";
            cout << states[i][j];
        }
        cout << endl;
    }
    cout << "check:" << endl;
    for (int i = 0; i < states[M-1].size(); i ++) {
        if (dp[M-1][i]) {
            cout << "\t" << i << " : " << dp[M-1][i] << endl;
        }
    }
}
int main() {
    while (cin >> M >> N) {
        memset(dp, 0, sizeof(dp));
        for (int i = 0; i < M; i ++) {
            for (int j = 0; j < N; j ++) {
                cin >> g[i][j];
            }
        }
        for (int i = 0; i < M; i ++) {
            states[i].clear();
            for (int j = 0; j < (1<<N); j ++) {
                bool flag = true;
                // 判断是否在岩石上种了玉米
                for (int k = 0; k < N; k ++) {
                    if (g[i][k] == 0 && j&(1<<k)) {
                        flag = false;
                        break;
                    }
                }
                // 判断是否相邻的格子都种了玉米
                if (flag) {
                    for (int k = 0; k < N-1; k ++) {
                        if (j&(1<<k) && j&(1<<(k+1))) {
                            flag = false;
                            break;
                        }
                    }
                }
                if (flag) {
                    states[i].push_back(j);
                }
            }
        }
        int sum = 0;
        for (int i = 0; i < M; i ++) {
            int sz = states[i].size();
            for (int j = 0; j < sz; j ++) {
                int p = states[i][j];
                if (i == 0) dp[i][p] = 1;
                else {
                    int sz2 = states[i-1].size();
                    for (int k = 0; k < sz2; k ++) {
                        int q = states[i-1][k];
                        if (!(p&q)) {
                            dp[i][p] += dp[i-1][q];
                            dp[i][p] %= MOD;
                        }
                    }
                }
                if (i == M-1) {
                    sum += dp[i][p];
                    sum %= MOD;
                }
            }
        }
        cout << sum << endl;
        // test();
    }
    return 0;
}
												
											POJ Corn Fields 状态压缩DP基础题的更多相关文章
- poj  Corn Fields   状态压缩dp。
		
Corn Fields Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 5763 Accepted: 3052 Descr ...
 - POJ 3254 Corn Fields(状态压缩DP)
		
Corn Fields Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 4739 Accepted: 2506 Descr ...
 - POJ 3254 Corn Fields (状态压缩DP)
		
题意:在由方格组成的矩形里面种草,相邻方格不能都种草,有障碍的地方不能种草,问有多少种种草方案(不种也算一种方案). 分析:方格边长范围只有12,用状态压缩dp好解决. 预处理:每一行的障碍用一个状态 ...
 - POJ3254 - Corn Fields(状态压缩DP)
		
题目大意 给定一个N*M大小的土地,土地有肥沃和贫瘠之分(每个单位土地用0,1来表示贫瘠和肥沃),要求你在肥沃的单位土地上种玉米,如果在某个单位土地上种了玉米,那么与它相邻的四个单位土地是不允许种玉米 ...
 - POJ 3254. Corn Fields 状态压缩DP (入门级)
		
Corn Fields Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 9806 Accepted: 5185 Descr ...
 - POJ 3254 Corn Fields  状态压缩DP (C++/Java)
		
id=3254">http://poj.org/problem? id=3254 题目大意: 一个农民有n行m列的地方,每一个格子用1代表能够种草地,而0不能够.放牛仅仅能在有草地的. ...
 - POJ 3254 Corn Fields状态压缩DP
		
下面有别人的题解报告,并且不止这一个状态压缩题的哦···· http://blog.csdn.net/accry/article/details/6607703 下面是我的代码,代码很挫,绝对有很大的 ...
 - poj - 3254 Corn Fields (状态压缩dp入门)
		
http://poj.org/problem?id=3254 参考:http://blog.csdn.net/accry/article/details/6607703 农夫想在m*n的土地上种玉米, ...
 - 【poj3254】Corn Fields  状态压缩dp
		
AC通道:http://vjudge.net/problem/POJ-3254 [题目大意] 农夫约翰购买了一处肥沃的矩形牧场,分成M*N(1<=M<=12; 1<=N<=12 ...
 
随机推荐
- SP10707 COT2 - Count on a tree II 莫队上树
			
题意:求一条链 \((u,v)\) 上不同的颜色数. 我们可以求出树的出栈入栈序(or 括号序?我也不确定). 图(from attack) 然后有一个很优美的性质: 设点 \(u\) 的入栈时间为 ...
 - 获取上一个页面的data
			
let pages = getCurrentPages();// 获取页面栈 let current = pages[pages.length - 1]; // 当前页面 let url = curr ...
 - 2017.10.2 国庆清北 D2T2 树上抢男主
			
/* 我只看懂了求LCA */ #include<iostream> #include<cstring> #include<cstdio> #include< ...
 - Python中多层List展平为一层
			
小书匠python 使用Python脚本的过程中,偶尔需要使用list多层转一层,又总是忘记怎么写搜索关键词,所以总是找了很久,现在把各种方法记录下来,方便自己也方便大家. 方法很多,现在就简单写8种 ...
 - spark sql 常用语句
			
在spark dataFrame数据结构里面使用sql语句查询数据 (因为是RDD和dataFrame数据是只读的,所以不能做修改,删除操作.) 首先将文本数据转换为DataFrame数据格式 有两种 ...
 - ArcGIS Enterprise 10.7.1新特性:批量发布服务
			
ArcGIS Enterprise 10.7.1提供了批量发布GIS服务的功能,能大大简化GIS系统管理员的工作量. 作为发布人员和管理人员,支持向Portal for ArcGIS添加云存储.文件共 ...
 - Day11:Flex布局
			
参考: 来源:http://www.ruanyifeng.com/blog/2015/07/flex-grammar.html 网页布局是css的一个重点. 盒子模型 display属性 positi ...
 - 基于腾讯云监控 API 的 Grafana App 插件开发
			
Tencent Cloud Monitor App Grafana 是一个开源的时序性统计和监控平台,支持例如 elasticsearch.graphite.influxdb 等众多的数据源,并以功能 ...
 - CF1214题解
			
D 因为可以用贡献2把起点终点堵掉,所以答案为0/1/2 0/2简单 1:方格可以理解为分层图,考虑每个能到达终点,起点能到达其的点,标记一下,对角线如果仅存在1则为必经之路 E \(d_i\le n ...
 - Centos7变动
			
Nmtui:网络配置图形界面 Systemctl:管理systemd的单元 Service:系统服务 Socket:进程间的通信 Busname: Target:多个unit构成的组,运行级别 Sna ...