UVALive 7344 I - Numbered Cards
来源:互联网 发布:双胞胎 双飞 知乎 编辑:程序博客网 时间:2024/04/29 17:16
题目描述:
You have N cards and each has an unique number between 1 and N written on it. In how many
ways can you select a non-empty subset of the cards such that the number written on any two of your
selected cards don’t have any common digits?
For example, when N = 12, {1, 2, 3}, {2, 11}, {3, 4, 5, 6, 7, 8, 9, 12} are some valid selections. But
{1, 2, 10}, {2, 5, 12} are not allowed.
Input
The first line of the input contains an integer T (T ≤ 15) which is the number of test cases. Each of
the following T lines denote a test case, containing an integer N (1 ≤ N < 109
).
Output
For each test case, output the case number followed by the number of subsets modulo 1000000007.
题解:
非常好的一道题目. 首先想到dp来表示之前已经用了几个数, 然后转移的时候用到了偏序(因为是集合的原因),我们强制让最后一个数包括最小的那个. 然后转移的g[2^i]是用3(4)进制状压的数位dp做.
重点:
1.dp的想法来做,状压
2.集合无序性,我们用偏序做.
3.二进制都是恰好一定要用掉这么多,不能采用用不超过这个范围(但没必要全用完)这样的思维,因为会有很多重复情况. ——这是赛场上差点犯的错误QAQ
4.用3进制状压:不能用,要用还没用,要用已经用过了至少一次
代码:
#include <iostream>#include <cstdio>#include <cstring>using namespace std;typedef long long ll;const int maxn = 1024 + 100;const int M = 1e9 + 7.1;int fac[20], n, g[maxn], f[maxn], d[20][1024 * 1024 + 100];int s[20];int add(int a, int b) { int c = a + b; if(c >= M) c -= M; return c;}int sub(int a, int b) { if(a < b) a += M; return a - b;}int dfs(int pos, int limit, int sta, int first) { //printf("222 %d\n", sta); if(pos < 0) { if(first) return 0; int flag = 1; for(int i = 0; i < 10; i++) { if((1 << (2 * i + 1)) & sta) { flag = 0; break; } } return flag; } if(limit == 0 && first == 0 && d[pos][sta] != -1) return d[pos][sta]; int ans = 0; for(int i = 0; i < 10; i++) { if(((1 << (2 * i) ) & sta) == 0 && !(i == 0 && first)) continue; if(first && i == 0) { ans = add(ans, dfs(pos - 1, 0, sta, 1)); continue; } int tmp = sta; if((1 << (2 * i + 1)) & sta) tmp = sta ^ (1 << (2 * i + 1)); if(limit) { if(i > s[pos]) continue; if(i == s[pos]) { ans = add(ans, dfs(pos - 1, 1, tmp, 0)); } else { ans = add(ans, dfs(pos - 1, 0, tmp, 0)); } } else { ans = add(ans, dfs(pos - 1, 0, tmp, 0)); } } if(!limit && !first) d[pos][sta] = ans; return ans;}void solve() { int sn = 0, tmp = n; while(tmp != 0) { s[sn] = tmp % 10; tmp /= 10; sn++; } // printf("333 %d\n", sn); g[0] = 0; g[1] = 0; for(int sta = 2; sta < (1 << 10); sta++) { int num = 0; for(int i = 0; i < 10; i++) { if((1 << i) & sta) num = num + (1<<(2 * i)) + (1 << (2 * i + 1)); } g[sta] = dfs(sn - 1, 1, num, 1); // if(sta <= 8) printf("111 %d %d\n", sta, g[sta]); // if(g[sta] != 0) printf("111 %d %d\n", sta, g[sta]); } memset(f, 0, sizeof(f)); f[0] = 1; for(int sta = 1; sta < (1 << 10); sta++) { int number; for(int k = 0; k < 10; k++) { if((1 << k) & sta) { number = k; break; } } for(int ss = ((sta - 1) & sta);ss != sta; ss = ((ss - 1) & sta)) { if((1 << number) & (sta - ss)) f[sta] = add(f[sta], (ll)f[ss] * (ll)g[sta - ss] % M); } // if(sta <= 8) printf("222 %d %d\n", sta, f[sta]); } int ans = 0; for(int sta = 1; sta < (1 << 10); sta++) { ans = add(ans, f[sta]); } printf("%d\n", ans);}int main() { //freopen("i.txt", "r", stdin); memset(d, -1, sizeof(d)); int ncase; scanf("%d", &ncase); for(int _ = 1; _ <= ncase; _++) { // memset(d, -1, sizeof(d)); printf("Case %d: ", _); scanf("%d", &n); solve(); } return 0;}
- UVALive 7344 I - Numbered Cards
- LA 7344 Numbered Cards(数位DP)
- Uva 7344 Numbered Cards (状压DP)
- UVALive 4384 Business Cards
- UVALive 6672 Bonus Cards
- UVALive 5811 Cards
- UVALive 7278 Game of Cards
- Throwing cards away I
- Throwing cards away I
- uva:Throwing cards away I
- UVa10935 - Throwing cards away I
- UVA10935 - Throwing cards away I
- uva10935 - Throwing cards away I
- 10935 - Throwing cards away I
- UVa10935 - Throwing cards away I
- Throwing cards away I uva1594
- UVA_10935: Throwing cards away I
- Throwing cards away I--队列
- Java统计字符串中各种字母个数
- reason: 'launch path not accessible' abort() called 路径获取错误:
- Kafka+Storm+HDFS整合实践
- 修复TortoiseCVS图标显示问题
- 7.Which two statements are true regarding the USING and ON clauses in table joins? (Choose two.)
- UVALive 7344 I - Numbered Cards
- Hive 中的 Join 问题
- ASCII-转义字符
- 从QProcess说开来
- Poj 3216 Prime Path
- 亚马逊AWS和阿里云的员工数量和单兵营收能力几何
- 刷新页面更换CSS样式表-对网上document.write方式的修正
- shell编程基础
- ios 更多 Url Schemes