插头dp--hdu1639
来源:互联网 发布:网络摄像头安装方法. 编辑:程序博客网 时间:2024/04/27 22:24
插头DP
hdoj 1693 Eat the Trees
解题报告详见:http://hi.baidu.com/fqq11679/blog/item/423bcd4a3d956bf983025c6d.html
考虑本题规模较小,处理的方式是逐格递推的状态压缩DP。
如上图,我们用F[i,j,k]表示轮廓线在i行j列出外凸,轮廓线状态为k的方案数。
这里k是一个c+1位二进制数,1表示轮廓线第i个单元有插头,0表示没有。
那么转移就考虑两种,第一种是换行,这个就要把k先右移一位,然后把k
的前两位转移成凸起,更新F[i+1,1,k']。
第二种就是直接右推一格,这个就是直接在k中找出凹角对应的两位数,转换
得到新状态k'然后更新F[i,j+1,k']。
至于k如何转k'只需考虑凹角的几种情况:
1.凹角为11(横竖都有插头):新状态k'的这两位均为0,因为两个度用完了。
2.凹角为01(只有横边有插头):新状态k'可以是01或者10。
3.凹角为10(只有竖边有插头):同上。
4.凹角为00(都没插头):要么11,要么00。(00的条件是此格为障碍)
这样Dp一下,最后的答案就是F[r][c][0]。
#include <iostream>#include <cstring>using namespace std; typedef __int64 lld; int n, m, ca = 1;int mp[12][12];lld dp[12][12][1<<12]; void solve() { int i, j, k, x, y, p, q, v, len1; memset( dp, 0, sizeof(dp) ); dp[0][m][0] = 1; len1 = 1<<(m+1); for( i=0; i<=n; ++i ) { for( j=1; j<=m; ++j ) { if( i == 0 && j < m ) continue; for( k=0; k<len1; ++k ) { if( j == m ) {//换行递推 if( i < n ) { v = k >> 1; p = 1 << m; q = 1 << (m - 1); x = v & p; y = v & q; if( x == 0 && y == 0 ) { if( mp[i+1][1] ) { if( m > 1 ) dp[i+1][1][v-x-y+p+q] += dp[i][j][k]; } else { dp[i+1][1][v-x-y] += dp[i][j][k]; } }else if( x == 0 && y != 0 ) { if( mp[i+1][1] ) { if( m > 1 ) dp[i+1][1][v-x-y+q] += dp[i][j][k]; dp[i+1][1][v-x-y+p] += dp[i][j][k]; } } } } else {//向右递推 v = k; p = 1 << (m - j); q = 1 << (m - j - 1); x = v & p; y = v & q; if( x == 0 && y == 0 ) { if( mp[i][j+1] ) { if( j < m-1 ) dp[i][j+1][v-x-y+p+q] += dp[i][j][k]; } else { dp[i][j+1][v-x-y] += dp[i][j][k]; } } else if ( x != 0 && y != 0 ) { if( mp[i][j+1] ) dp[i][j+1][v-x-y] += dp[i][j][k]; } else { if( mp[i][j+1] ) { if( j < m-1 ) dp[i][j+1][v-x-y+q] += dp[i][j][k]; dp[i][j+1][v-x-y+p] += dp[i][j][k]; } } } } } } printf( "Case %d: There are %I64d ways to eat the trees.\n", ca++, dp[n][m][0] );} int main() {// freopen("c:/aaa.txt", "r", stdin); int T, i, j; scanf( "%d", &T ); while( T-- ) { scanf( "%d %d", &n, &m ); for( i=1; i<=n; ++i ) { for( j=1; j<=m; ++j ) { scanf( "%d", &mp[i][j] ); } } solve(); } return 0;}
- 插头dp--hdu1639
- 插头DP
- 插头dp
- 插头dp
- 插头dp
- 插头DP
- 插头dp
- hdu 1693 插头dp
- 插头DP【入门】
- hdu 4064 (插头DP)
- poj 3133 插头Dp
- HDU-1693-插头dp
- POJ-1739-插头dp
- 插头DP(HDOJ1693)初识
- 【Learning】适妞来学 插头 dp
- tongji 30029 插头dp
- Hdu 1693 插头dp
- ZOJ 3466 插头dp
- cognos中如何设置自动邮箱发送功能
- NY--8 -- 一种排序 [水]
- Sublime Text2 C++环境搭建
- 大数据初创企业可以在Facebook身上寻找灵(比特网)
- HDU 1003 Max Sum - from lanshui_Yang
- 插头dp--hdu1639
- 如何删去csdn博文中的段落标记(缩小换行行距)?
- hash函数解析
- UE使用技巧
- 为什么要使用抽象函数的简单示例
- ZOJ 3633Alice's present
- 设置Activity进入退出动画的两种方法
- Xamarin Mono For Android 4.8.00013 完整离线安装破解版(C#开发Android、IOS工具)
- iPhone开发的一些小技巧