hdu 4352 数位DP
2013-08-25 22:18
232 查看
这一题要用状态压缩,不然你会TLE到死的。
但是一开始的时候我也想不通为什么状态压缩能够节省时间,最后发现在状态压缩的时候用了点规律。
比如说 对于 1672345这个状态, 开始时候保存167 然后进行到第四位的时候 用2 替换6然后 用4替换7 然后增加5 这样DFS更深之后状态就变成了12345 这样就实现了在2345虽然都小于7但是还是能够更新。(利用了注释 11111 和 22222 )
还有应该把算出来的dp保存起来 供下个测试使用。注意还有[K]这个维度!!!!!
还有一点!!!!!!!!!我敲代码的时候把1敲成了i 连测试都过不了 找了半天啊!!!!!!!!!!都快瞎了我的眼啊!!!!!!!!!坑!!!!
![](http://static.blog.csdn.net/xheditor/xheditor_emot/default/cry.gif)
![](http://static.blog.csdn.net/xheditor/xheditor_emot/default/cry.gif)
AC代码如下:
但是一开始的时候我也想不通为什么状态压缩能够节省时间,最后发现在状态压缩的时候用了点规律。
比如说 对于 1672345这个状态, 开始时候保存167 然后进行到第四位的时候 用2 替换6然后 用4替换7 然后增加5 这样DFS更深之后状态就变成了12345 这样就实现了在2345虽然都小于7但是还是能够更新。(利用了注释 11111 和 22222 )
还有应该把算出来的dp保存起来 供下个测试使用。注意还有[K]这个维度!!!!!
还有一点!!!!!!!!!我敲代码的时候把1敲成了i 连测试都过不了 找了半天啊!!!!!!!!!!都快瞎了我的眼啊!!!!!!!!!坑!!!!
![](http://static.blog.csdn.net/xheditor/xheditor_emot/default/cry.gif)
![](http://static.blog.csdn.net/xheditor/xheditor_emot/default/cry.gif)
AC代码如下:
#include <iostream> #include <cstring> #include <cstdio> using namespace std; __int64 dp[20][1<<10][11];//不能少了[K]这个维度,不然会超时!!! __int64 L, R, K; int digit[20]; int len; __int64 DFS( int pos, int length, int statu, bool limit ){// 表示 进行到第pos位、最长子序列为length、序列为statu、状态是limit 时还有多少种情况!!! if( pos == 0 ){ return length == K; } if( !limit && dp[pos][statu][K] != -1 ){ return dp[pos][statu][K]; } __int64 ans = 0; int end = limit ? digit[pos] : 9; for( int i = 0; i <= end; i++ ){ if( statu || i ){ if( statu < ( 1 << i ) ){//1111111111 ans += DFS( pos - 1, length + 1, statu | ( 1 << i ), limit && i == end ); }else if( statu & ( 1 << i ) ){ ans += DFS( pos - 1, length, statu, limit && i == end ); }else{//222222222222 for( int j = i + 1; j <= 9; j++ ){ if( statu & ( 1 << j ) ){ ans += DFS( pos - 1, length, ( statu | ( 1 << i ) ) ^ ( 1 << j ), limit && i == end ); break; } } } }else{ ans += DFS( pos - 1, 0, 0, limit && i == end ); } } if( !limit ){ dp[pos][statu][K] = ans; } return ans; } __int64 solve( __int64 N ){ if( N == 0 ){ return 0; } len = 0; while( N ){ digit[++len] = N % 10; N /= 10; } return DFS( len, 0, 0, true ); } int main(){ int T, Case = 1; cin >> T; memset( dp, -1, sizeof( dp ) ); while( T-- ){ cin >> L >> R >> K; printf( "Case #%d: %I64d\n", Case++, solve( R ) - solve( L - 1 ) ); } return 0; }
相关文章推荐
- HDU 4352 XHXJ's LIS (数位DP+状态压缩)
- 数位dp+LIS+状态压缩-hdu-4352-XHXJ's LIS
- hdu 4352 状态压缩+数位DP
- HDU 4352 XHXJ's LIS(数位dp)
- hdu 4352 状态压缩+数位DP
- HDU 4352 XHXJ's LIS(状态压缩+数位dp)
- HDU 4352 XHXJ's LIS(数位dp&状态压缩)
- hdu 4352 状态压缩+数位DP
- hdu 4352 数位DP
- HDU 4352 XHXJ's LIS(数位DP)
- hdu 4352 状态压缩+数位DP
- HDU 4352 XHXJ's LIS(数位DP)
- HDU - 4352 XHXJ's LIS (数位DP&记忆化dfs&位运算)好题
- hdu 4352 状态压缩+数位DP
- HDU-4352-数位dp,LIS
- HDU 4352 数位DP + LIS
- HDU 4352 XHXJ's LIS (数位DP+LIS+状态压缩)
- hdu 4352 状态压缩+数位DP
- HDU 4352 XHXJ's LIS 数位dp
- hdu 4352 XHXJ's LIS 数位DP