uva 11825 状态压缩DP
2014-05-31 21:53
330 查看
妈蛋啊 一开始一直以为是树形dp的。。。。。
然后这题其实可以转化成状态压缩DP
Pi表示第i个点可以覆盖到的点
然后不就有了p1 p2 p3.。。。pn嘛
然后就是求最多可以分成多少组使每组并起来是全集
然后dp[s]表示集合s可以分成多少组
然后dp[s] = max(dp[s0])+ 1
s0是s的子集
so。。。。。
AC代码如下:
然后这题其实可以转化成状态压缩DP
Pi表示第i个点可以覆盖到的点
然后不就有了p1 p2 p3.。。。pn嘛
然后就是求最多可以分成多少组使每组并起来是全集
然后dp[s]表示集合s可以分成多少组
然后dp[s] = max(dp[s0])+ 1
s0是s的子集
so。。。。。
AC代码如下:
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> using namespace std; int N, M, p[20]; int dp[1<<20]; int cover[1<<20]; bool judge( int s ){ int temp = 0; if( cover[s] != -1 ){ return cover[s];//不记忆一下会TLE } for( int i = 0; i < N; i++ ){ if( ( 1 << i ) & s ){ temp |= p[i]; } } if( temp == ( 1 << N ) - 1 ){ return cover[s] = true; }else{ return cover[s] = false; } } int main(){ int Case = 1; while( scanf( "%d", &N ) && N ){ for( int i = 0; i < N; i++ ){ scanf( "%d", &M ); int t = 1 << i; for( int j = 0; j < M; j++ ){ int temp; scanf( "%d", &temp ); t |= 1 << temp; } p[i] = t; } dp[0] = 0; memset( cover, -1, sizeof( cover ) ); for( int i = 0; i < ( 1 << N ); i++ ){ dp[i] = 0; for( int s = i; s ; s = i & ( s - 1 ) ){ if( judge( s ) ){ dp[i] = max( dp[i], dp[i^s] + 1 ); } } } printf( "Case %d: %d\n", Case++, dp[(1<<N)-1] ); } return 0; }
相关文章推荐
- uva 11825 Hackers' Crackdown(状态压缩DP)
- UVa 11825 黑客的攻击(状态压缩dp)
- UVA 11825 状态压缩DP+子集思想
- UVA 11825 集合枚举 状态压缩 dp
- UVA 11825 - Hackers' Crackdown 状态压缩 dp 枚举子集
- uva 11825 ,Hacker's Crackdown 状态压缩 dp
- UVA 11825 状态压缩DP
- uva 11825(dp + 状态压缩)
- Uva 11825 - Hackers’ Crackdown 状态压缩DP
- Hacker's Crackdown(UVa 11825)状态压缩dp+数学模型
- UVa 11825 状态压缩DP
- UVa 11825 Hackers’ Crackdown / 状态压缩DP
- UVA 11825 - Hackers' Crackdown 状态压缩 dp 枚举子集
- UVA 11825 Hackers' Crackdown 状态压缩dp
- UVa 11825 Hackers' Crackdown (状态压缩DP)
- Hackers’ Crackdown-----UVA11825-----DP+状态压缩
- Uva - 11825 - Hackers' Crackdown(状态压缩dp)
- uva11825 - Hackers' Crackdown(状态压缩dp)
- UVA 11825 Hackers' Crackdown DP+状态压缩 -
- Hackers’ Crackdown-----UVA11825-----DP+状态压缩