ZOJ 1100 Mondriaan's Dream
来源:互联网 发布:mysql 5.7.15安装图解 编辑:程序博客网 时间:2024/04/29 21:24
解题报告没看懂,先存
/*
这至少是一道中等难度的动态规划题目,首先用面积
的奇偶性,当高度和宽度都为奇数时显然答案为0;
其次,把每一列的砖块压缩为二进制编码,搜索上一
列到当前列的状态转化是否能够达到,接着DP;
对于每一个位置,我们有三种放置方法:
1.水平放置
2.竖直放置
3.不放置
4. n为当行的位置,初始化n, from, to都为0;对应以
上三种放置方法,from, to的调整为:
1. n = n + 2, from=(from*2+1)*2+1=from*4+3, to=to*4+3;
2. n = n + 1, from=from*2+1, to=to*2 (即不放置);
3. n = n + 1, from=from*2, to=to*2+1 (即竖直放置);
上图to值编码a1=((((3*2+1)*4+3)*4+3))*2*2)*4+3=2035<=2^11-1;
上图from值编码a0=((((((1*2+1)*2+1)*2+1)*4+3)*2+1)*2*2)*4+3=2035<=2^11-1;
图1的to值等于图2的from值,这样就能匹配DP了。
*/
/*
**************************************************
ZOJ 1100 Mondriaan's Dream
Tips: DP 'double'
memory 292K
runtime 0MS
3WA 1AC
Accepted time 2009-02-21 11:55:36
**************************************************
*/
#include<iostream>
#include<string>
using namespace std;
int a[2][10000],w,h,loop;
//int b[2][2050];
double b[2][2050];
void dfs(int n, int from, int to){
if(n>h) return;
if(n==h){
a[0][loop]=from;
a[1][loop]=to;
loop++;
return;
}
dfs(n+2,from<<2|3,to<<2|3);
dfs(n+1,from<<1|1,to<<1);
dfs(n+1,from<<1,to<<1|1);
}
void dp(){
int i,j;
memset(b,0,sizeof(b));
b[0][(1<<h)-1]=1;
for(i=0;i<w;i++){
for(j=0;j<loop;j++){
b[(i+1)%2][a[1][j]]+=b[i%2][a[0][j]];
}
memset(b[i%2],0,sizeof(b[0]));
}
}
int main(){
while(scanf("%d%d",&h,&w)!=EOF){
if(h==0 && w==0) break;
if((w*h)%2){
printf("0\n");
continue;
}
if(h>w){
h=h^w;w=w^h;h=h^w;
}
loop=0;
dfs(0,0,0);
dp();
printf("%.0lf\n",b[w%2][(1<<h)-1]);
}
return 0;
}
/*
这又是个经典的DP问题,但是下面的算法源自组合数学。
用1*2的砖铺满一个n*m的房间,有多少种方法?
在网上搜到一个国外数学家的论文,找到一个公式,
详细见Statistical Mechanics of Dimers on a Plane Lattice
具体公式
for(i,1......【n/2】)
for(j,1.......【m/2】)
result*=4cos(pi+i/(h+1))^2+4cos(pi+j/(w+1))^2;
注意 result的初始值为1,【】表示向下取整,pi要尽量精确
最后的结果去整数部分就是答案
另外按照“面积守恒定理”房间面积为奇数的肯定没办法铺满;
*/
/*
*********************************************
ZOJ 1100 Mondriaan's Dream
Tips: math
memory 184K
runtime 0MS
1AC
Accepted time 2009-02-21 21:26:41
*********************************************
*/
#include <cstdlib>
#include <iostream>
#include <cmath>
#define Pi 2*acos(0)
using namespace std;
int h,w,endh,endw;
double result;
int main(){
while(scanf("%d%d",&h,&w)!=EOF){
if(h==0 && w==0) break;
if(h*w%2){
printf("0\n");
continue;
}
result=1.0;
endh=h/2;
endw=w/2;
for(int i=1;i<=endh;++i){
for(int j=1;j<=endw;++j){
result*=4*(pow(cos(Pi*i/(h+1.0)),2.0)+pow(cos(Pi*j/(w+1.0)),2.0));
}
}
printf("%0.0f\n",result);
}
return 0;
}
这至少是一道中等难度的动态规划题目,首先用面积
的奇偶性,当高度和宽度都为奇数时显然答案为0;
其次,把每一列的砖块压缩为二进制编码,搜索上一
列到当前列的状态转化是否能够达到,接着DP;
对于每一个位置,我们有三种放置方法:
1.水平放置
2.竖直放置
3.不放置
4. n为当行的位置,初始化n, from, to都为0;对应以
上三种放置方法,from, to的调整为:
1. n = n + 2, from=(from*2+1)*2+1=from*4+3, to=to*4+3;
2. n = n + 1, from=from*2+1, to=to*2 (即不放置);
3. n = n + 1, from=from*2, to=to*2+1 (即竖直放置);
上图to值编码a1=((((3*2+1)*4+3)*4+3))*2*2)*4+3=2035<=2^11-1;
上图from值编码a0=((((((1*2+1)*2+1)*2+1)*4+3)*2+1)*2*2)*4+3=2035<=2^11-1;
图1的to值等于图2的from值,这样就能匹配DP了。
*/
/*
**************************************************
ZOJ 1100 Mondriaan's Dream
Tips: DP 'double'
memory 292K
runtime 0MS
3WA 1AC
Accepted time 2009-02-21 11:55:36
**************************************************
*/
#include<iostream>
#include<string>
using namespace std;
int a[2][10000],w,h,loop;
//int b[2][2050];
double b[2][2050];
void dfs(int n, int from, int to){
if(n>h) return;
if(n==h){
a[0][loop]=from;
a[1][loop]=to;
loop++;
return;
}
dfs(n+2,from<<2|3,to<<2|3);
dfs(n+1,from<<1|1,to<<1);
dfs(n+1,from<<1,to<<1|1);
}
void dp(){
int i,j;
memset(b,0,sizeof(b));
b[0][(1<<h)-1]=1;
for(i=0;i<w;i++){
for(j=0;j<loop;j++){
b[(i+1)%2][a[1][j]]+=b[i%2][a[0][j]];
}
memset(b[i%2],0,sizeof(b[0]));
}
}
int main(){
while(scanf("%d%d",&h,&w)!=EOF){
if(h==0 && w==0) break;
if((w*h)%2){
printf("0\n");
continue;
}
if(h>w){
h=h^w;w=w^h;h=h^w;
}
loop=0;
dfs(0,0,0);
dp();
printf("%.0lf\n",b[w%2][(1<<h)-1]);
}
return 0;
}
/*
这又是个经典的DP问题,但是下面的算法源自组合数学。
用1*2的砖铺满一个n*m的房间,有多少种方法?
在网上搜到一个国外数学家的论文,找到一个公式,
详细见Statistical Mechanics of Dimers on a Plane Lattice
具体公式
for(i,1......【n/2】)
for(j,1.......【m/2】)
result*=4cos(pi+i/(h+1))^2+4cos(pi+j/(w+1))^2;
注意 result的初始值为1,【】表示向下取整,pi要尽量精确
最后的结果去整数部分就是答案
另外按照“面积守恒定理”房间面积为奇数的肯定没办法铺满;
*/
/*
*********************************************
ZOJ 1100 Mondriaan's Dream
Tips: math
memory 184K
runtime 0MS
1AC
Accepted time 2009-02-21 21:26:41
*********************************************
*/
#include <cstdlib>
#include <iostream>
#include <cmath>
#define Pi 2*acos(0)
using namespace std;
int h,w,endh,endw;
double result;
int main(){
while(scanf("%d%d",&h,&w)!=EOF){
if(h==0 && w==0) break;
if(h*w%2){
printf("0\n");
continue;
}
result=1.0;
endh=h/2;
endw=w/2;
for(int i=1;i<=endh;++i){
for(int j=1;j<=endw;++j){
result*=4*(pow(cos(Pi*i/(h+1.0)),2.0)+pow(cos(Pi*j/(w+1.0)),2.0));
}
}
printf("%0.0f\n",result);
}
return 0;
}
0 0
- ZOJ 1100 Mondriaan's Dream
- zoj 1100 Mondriaan's Dream
- ZOJ 1100 Mondriaan's Dream
- zoj 1100 - Mondriaan's Dream
- ZOJ 1100 Mondriaan's Dream
- ZOJ 1100Mondriaan's Dream
- Mondriaan's Dream (zoj 1100 状压dp)
- ZOJ 1100 Mondriaan's Dream【状态压缩】【DP】【DFS】
- poj 2411 && zoj 1100 Mondriaan's Dream ———状态压缩dp
- zoj 1100&& poj2411 Mondriaan's Dream (dfs&&枚举&&状态压缩dp)好题
- [pku2411]Mondriaan's Dream
- POJ2411 Mondriaan's Dream
- POJ2411--Mondriaan's Dream
- POJ2411 Mondriaan's Dream
- poj2411 Mondriaan's Dream
- OpenJudge1413 Mondriaan's Dream
- openjudge Mondriaan's Dream
- Mondriaan's Dream POJ2411
- [Linux网络编程]socket编程学习(一)——基本API
- 程序员趣味读物:谈谈Unicode编码
- 使用dup和dup2重定向和还原
- 夏季痔疮易发
- 关于android布局的两个属性dither和tileMode
- ZOJ 1100 Mondriaan's Dream
- 程序员必备:10个匿名浏览网页的隐私保护工具
- Linux命令记录
- 《富爸爸穷爸爸》读书笔记(三)
- 【小白笔记】PHP学习之路 (30) --绘制文字及相关库函数
- volatile变量类型的详细说明
- ubuntu IDE(eclipse ,intellij)安装
- GCD文档
- ORA-12514 TNS 监听程序当前无法识别连接描述符中请求服务 的解决方法 此博文包含图片 (2011-01-20 13:50:37)转载▼ 标签: it分类: 技术 早上同事用PL/SQ