FZU 1977 Pandora adventure (DP)
题意:给定一个图,X表示不能走,O表示必须要走,*表示可走可不走,问你多少种走的法,使得形成一个回路。
析:
代码如下:
- #pragma comment(linker, "/STACK:1024000000,1024000000")
- #include <cstdio>
- #include <string>
- #include <cstdlib>
- #include <cmath>
- #include <iostream>
- #include <cstring>
- #include <set>
- #include <queue>
- #include <algorithm>
- #include <vector>
- #include <map>
- #include <cctype>
- #include <cmath>
- #include <stack>
- #include <sstream>
- #include <list>
- #include <assert.h>
- #include <bitset>
- #define debug() puts("++++");
- #define gcd(a, b) __gcd(a, b)
- #define lson l,m,rt<<1
- #define rson m+1,r,rt<<1|1
- #define fi first
- #define se second
- #define pb push_back
- #define sqr(x) ((x)*(x))
- #define ms(a,b) memset(a, b, sizeof a)
- //#define sz size()
- #define pu push_up
- #define pd push_down
- #define cl clear()
- #define all 1,n,1
- #define FOR(i,x,n) for(int i = (x); i < (n); ++i)
- #define freopenr freopen("in.txt", "r", stdin)
- #define freopenw freopen("out.txt", "w", stdout)
- using namespace std;
- typedef long long LL;
- typedef unsigned long long ULL;
- typedef pair<int, int> P;
- const int INF = 0x3f3f3f3f;
- const double inf = 1e20;
- const double PI = acos(-1.0);
- const double eps = 1e-8;
- const int maxn = 10 + 10;
- const int maxm = 1e5 + 10;
- const int mod = 50007;
- const int dr[] = {-1, 0, 1, 0};
- const int dc[] = {0, -1, 0, 1};
- const char *de[] = {"0000", "0001", "0010", "0011", "0100", "0101", "0110", "0111", "1000", "1001", "1010", "1011", "1100", "1101", "1110", "1111"};
- int n, m;
- const int mon[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
- const int monn[] = {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
- inline bool is_in(int r, int c) {
- return r >= 0 && r < n && c >= 0 && c < m;
- }
- struct Hash{
- int head[mod], next[maxm], sz;
- LL state[maxm], f[maxm];
- void clear(){ sz = 0; ms(head, -1); }
- void push(LL st, LL ans){
- int h = st % mod;
- for(int i = head[h]; ~i; i = next[i])
- if(st == state[i]){
- f[i] += ans;
- return ;
- }
- f[sz] = ans;
- state[sz] = st;
- next[sz] = head[h];
- head[h] = sz++;
- }
- };
- Hash dp[2];
- int isend; // is or not form loop
- int code[maxn], ch[maxn];
- int a[maxn][maxn]; // 1 must go 2 go or not
- char s[maxn];
- void decode(int m, LL st){
- for(int i = m; i >= 0; --i){
- code[i] = st&7;
- st >>= 3;
- }
- isend = st&1; // the highest bit
- }
- LL encode(int m){
- LL st = isend;
- int cnt = 1; ms(ch, -1);
- ch[0] = 0;
- for(int i = 0; i <= m; ++i){
- if(ch[code[i]] == -1) ch[code[i]] = cnt++;
- st <<= 3;
- st |= ch[code[i]];
- }
- return st;
- }
- void shift(int m){
- for(int i = m; i; --i) code[i] = code[i-1];
- code[0] = 0;
- }
- void dpblank(int i, int j, int cur){
- for(int k = 0; k < dp[cur].sz; ++k){
- decode(m, dp[cur].state[k]);
- int left = code[j-1];
- int up = code[j];
- if(isend){ // already form loop
- if(up || left || a[i][j] == 1) continue;
- code[j] = code[j-1] = 0;
- if(j == m) shift(m);
- dp[cur^1].push(encode(m), dp[cur].f[k]);
- continue;
- }
- if(up && left){
- if(up == left){ // last grid
- code[j-1] = code[j] = 0;
- isend = 1;
- if(j == m) shift(m);
- dp[cur^1].push(encode(m), dp[cur].f[k]);
- }
- else{
- code[j] = code[j-1] = 0;
- for(int i = 0; i <= m; ++i)
- if(code[i] == up) code[i] = left;
- if(j == m) shift(m);
- dp[cur^1].push(encode(m), dp[cur].f[k]);
- }
- }
- else if(up || left){
- int t = max(up, left);
- if(a[i][j+1]){
- code[j] = t;
- code[j-1] = 0;
- dp[cur^1].push(encode(m), dp[cur].f[k]);
- }
- if(a[i+1][j]){
- code[j] = 0;
- code[j-1] = t;
- if(j == m) shift(m);
- dp[cur^1].push(encode(m), dp[cur].f[k]);
- }
- }
- else{
- if(a[i+1][j] && a[i][j+1]){
- code[j] = code[j-1] = 14;
- dp[cur^1].push(encode(m), dp[cur].f[k]);
- }
- if(a[i][j] == 2){
- code[j] = code[j-1] = 0;
- if(j == m) shift(m);
- dp[cur^1].push(encode(m), dp[cur].f[k]);
- }
- }
- }
- }
- void dpblock(int i, int j, int cur){
- for(int k = 0; k < dp[cur].sz; ++k){
- decode(m, dp[cur].state[k]);
- code[j] = code[j-1] = 0;
- if(j == m) shift(m);
- dp[cur^1].push(encode(m), dp[cur].f[k]);
- }
- }
- int main(){
- int T; cin >> T;
- for(int kase = 1; kase <= T; ++kase){
- scanf("%d %d", &n, &m);
- ms(a, 0);
- for(int i = 1; i <= n; ++i){
- scanf("%s", s + 1);
- for(int j = 1; j <= m; ++j){
- if(s[j] == 'O') a[i][j] = 1; // must go
- else if(s[j] == '*') a[i][j] = 2; // not need go
- }
- }
- int cur = 0;
- dp[cur].cl; dp[cur].push(0, 1);
- for(int i = 1; i <= n; ++i)
- for(int j = 1; j <= m; ++j){
- dp[cur^1].cl;
- if(a[i][j]) dpblank(i, j, cur);
- else dpblock(i, j, cur);
- cur ^= 1;
- }
- LL ans = 0;
- for(int i = 0; i < dp[cur].sz; ++i)
- ans += dp[cur].f[i];
- printf("Case %d: %I64d\n", kase, ans);
- }
- return 0;
- }
FZU 1977 Pandora adventure (DP)的更多相关文章
- FZU 1977 Pandora adventure (插头DP,常规)
题意:有一个n*m矩阵,其中有些格子必走,有些格子不可走,其他格子是可走也可不走,问有多少条哈密顿回路? 思路: 本来是一道很简单的题,代码写多了连白痴bug都查不出了,竟然用i>=ex& ...
- 【FZU】1977 Pandora adventure
http://acm.fzu.edu.cn/problem.php?pid=1977 题意:n×m的网格,有3种格子,'O'必须经过.'*'可以选择经过.'X'不能经过.现在要求路径经过所有'O'且是 ...
- FZU1977 Pandora adventure —— 插头DP
题目链接:https://vjudge.net/problem/FZU-1977 Problem 1977 Pandora adventure Accept: 597 Submit: 2199 ...
- FZU - 2204 简单环形dp
FZU - 2204 简单环形dp 题目链接 n个有标号的球围成一个圈.每个球有两种颜色可以选择黑或白染色.问有多少种方案使得没有出现连续白球7个或连续黑球7个. 输入 第一行有多组数据.第一行T表示 ...
- FZU 1025 状压dp 摆砖块
云峰菌曾经提到过的黄老师过去讲课时的摆砖块 那时百度了一下题目 想了想并没有想好怎么dp 就扔了 这两天想补动态规划知识 就去FZU做专题 然后又碰到了 就认真的想并且去做了 dp思想都在代码注释里 ...
- FZU 2092 收集水晶 dp+bfs
定义dp[t][x1][y1][x2][y2]为在t时刻,人走到x1,y1,影子走到x2,y2所获得最大价值 最终就是所有的dp[max][..][..][..][..]的最大值 然后递推也很自然,枚 ...
- FZU 2113(数位dp)
题目连接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=38054 题意:求区间[a,b]中包含'1'的个数. 分析:数位dp ...
- FZU 1502 Letter Deletion(DP)
Description You are given two words (each word consists of upper-case English letters). Try to delet ...
- [FZU1977] Pandora adventure
来学插头DP了= = GDKOI前觉得不会考数位DP,GDOI前觉得插头DP用不上.. 结果令人伤感>_< 这题并不用增加状态.. 只要在形成环的时候,让形成环的位置在最后一个必走点之后, ...
随机推荐
- CF gym101933 K King's Colors——二项式反演
题目:http://codeforces.com/gym/101933/problem/K 每个点只要和父亲不同色就行.所以 “至多 i 种颜色” 的方案数就是 i * ( i-1 )n-1 . #i ...
- 360全景技术支持中心(KRPanoGUI三维全景制作软件)
http://www.360pano.cn/ http://www.360pano.cn/88/ http://www.suse.edu.cn/qjmy/hd/index.html
- Android wm指令用法详解
wm 是查看和设置显示信息的指令,此指令只能临时调试使用. wm:查看 wm 指令信息 $ adb shell root@rk3288:/ # wm wm usage: wm [subcommand] ...
- SpringCloud初体验:一、Eureka 服务的注册与发现
Eureka :云端服务发现,一个基于 REST 的服务,用于定位服务,以实现云端中间层服务发现和故障转移. Eureka 可以大致理解为 房产中介 和 房东 的关系,房东想让租客租房子,首先要把房子 ...
- py基础3--函数,递归,内置函数
本节内容 函数基本语法及特性 参数与局部变量 返回值 嵌套函数 递归 匿名函数 函数式编程介绍 高阶函数 内置函数 1. 函数基本语法及特性 背景提要 现在老板让你写一个监控程序,监控服务器的系统状况 ...
- CentOS下MySQL的彻底卸载
#################CentOS7下MySQL的卸载#################### 1:查看MySQL是否安装: 方式1: [root@localhost usr]# yu ...
- Oracle11g 搭建单实例DataGuard (转载)
原文:http://blog.itpub.net/29324876/viewspace-1246133/ 环境:主备库都为单实例并且数据库SID相同 OS:red hat 6.5 Oracle:11. ...
- springboot 2.0 自定义redis自动装配
首先创建maven项目 pom.xml: <?xml version="1.0" encoding="UTF-8"?> <project xm ...
- 新手之:SpringBoot ——Reids主从哨兵整合(CentOS7)
一.Redis主从搭建(一台服务器模拟多个端口) 结构图:) 1.确保安装了Redis,我装在了/opt/redis目录下.可通过"whereis redis-cli"命令查看是否 ...
- Python Web框架——Flask
简介 Flask是一个基于Python开发并且依赖jinja2模板和Werkzeug WSGI服务的一个微型框架,对于Werkzeug本质是Socket服务端,其用于接收http请求并对请求进行预处理 ...