hdu 4352 XHXJ's LIS 状压数位dp
2016-09-01 20:49
344 查看
求a - b 的按每位值来最长lis长度为k的个数
当求lis时 每加入一个数看此时的lis中有没有数大于等于它且前一个数小于它,有的话将这个位置替换成这个数,没有的话把它填入到末尾 lis+1
所以dp[i][sym][len] 代表 推到第i位,此时组成状态为sym, 最后lis长度为len的方案数
注意处理前导0
当求lis时 每加入一个数看此时的lis中有没有数大于等于它且前一个数小于它,有的话将这个位置替换成这个数,没有的话把它填入到末尾 lis+1
所以dp[i][sym][len] 代表 推到第i位,此时组成状态为sym, 最后lis长度为len的方案数
注意处理前导0
#include<cstdio> #include<algorithm> #include<iostream> #include<cstring> #define LL long long using namespace std; LL dp[21][1026][23]; LL l, x[100]; LL update(LL n, LL va) { for(int i = va; i<= 9; i++) if(n & (1 << i)) return n ^ (1 << i) | (1 << va); return n | (1 << va); } LL getNum(LL n) { int sum = 0; while(n) { if(n & 1) sum++; n >>= 1; } return sum; } LL dfs(LL i, bool e, LL pre, LL len, bool sym) //状态 { if(i == -1) return getNum(pre) == len; if(e && dp[i][pre][len] != -1) return dp[i][pre][len]; int Max = e ? 9 : x[i]; LL ans = 0; for(int j = 0; j <= Max; j++) ans += dfs(i - 1, !(!e && j == x[i]), sym||j? update(pre, j) : 0, len, sym || j); if(e) dp[i][pre][len] = ans; return ans; } LL cal(LL n, LL len) { l = 0; while(n) { x[l++] = n % 10; n /= 10; } return dfs(l - 1, 0, 0, len, 0); } int main() { memset(dp, -1, sizeof(dp)); int t, i1 = 1; scanf("%d", &t); while(t--) { LL a, b, k; scanf("%I64d %I64d %I64d", &a, &b, &k); printf("Case #%d: %I64d\n", i1++, cal(b, k) - cal(a - 1, k)); } return 0; }
相关文章推荐
- HDU_4352 _ XHXJ's LIS (数位Dp+LIS + 状压)
- 【hdu】4352 XHXJ's LIS【状压+数位dp】
- HDU 4352 XHXJ's LIS ★(数位DP)
- HDU 4352 XHXJ's LIS 数位dp+lis
- HDU 4352 XHXJ's LIS(数位DP+LIS+状态压缩)
- HDU 4352 XHXJ's LIS ★(数位DP)
- hdoj 4352 XHXJ's LIS 【数位dp】
- 数位dp+LIS+状态压缩-hdu-4352-XHXJ's LIS
- 【HDU 4352】 XHXJ's LIS (数位DP+状态压缩+LIS)
- HDU 4352 XHXJ's LIS 数位dp
- HDU 4352 XHXJ's LIS【数位DP】
- hdu 4352 XHXJ's LIS(LIS+数位DP,5级)
- HDU 4352 XHXJ's LIS 数位dp
- hdu 4352 XHXJ's LIS(数位dp进阶,LIS, 状态压缩)
- hdu 4352 XHXJ's LIS(数位DP)
- hdu_4352_XHXJ's LIS(数位DP+状态压缩)
- HDU 4352 XHXJ's LIS(数位DP)
- HDU 4352 XHXJ's LIS(数位DP)
- HDU 4352 XHXJ's LIS 数位DP + 状压
- hdu 4352 XHXJ's LIS(数位dp)