第一道 状态压缩dp
2014-03-12 23:23
155 查看
题目:Codeforces
Round #235
D. Roman and Numbers
题目链接:http://codeforces.com/contest/401/problem/D
题目意思:有两个数n和m,问由n的组成数字组成的,能被m整出的数的个数。
解题思路:第一次接触状态压缩dp,以前只是听过没看过。看的大神们的思路和大神们的代码。
其中mask是用二进制表示的第几位的使用情况,用0和1表示。第二个参数是余数;在写最后一层循
环的时候看到了两种写法。一种是正着的循环(没去重复),最后再把结果除去每个重复数字个数的
阶乘。第二种方法是下面代码这种,倒着循环,增加一个pre标记,去除重复。(ps:不是很懂,感
觉好像是保证每次用的都是第一个数字吧)。
Round #235
D. Roman and Numbers
题目链接:http://codeforces.com/contest/401/problem/D
题目意思:有两个数n和m,问由n的组成数字组成的,能被m整出的数的个数。
解题思路:第一次接触状态压缩dp,以前只是听过没看过。看的大神们的思路和大神们的代码。
f[mask | 1 << i][(k*10+a[i]) % m] += f[mask][k];
其中mask是用二进制表示的第几位的使用情况,用0和1表示。第二个参数是余数;在写最后一层循
环的时候看到了两种写法。一种是正着的循环(没去重复),最后再把结果除去每个重复数字个数的
阶乘。第二种方法是下面代码这种,倒着循环,增加一个pre标记,去除重复。(ps:不是很懂,感
觉好像是保证每次用的都是第一个数字吧)。
using namespace std; #define long long long long f[1 << 18][100]; int a[20]; int main(){ long n, m; int N = 0; cin >> n >> m; for( ; n>=0; n /=10) a[N++] = n%10; sort(a,a+N); int mask, k; f[0][0] = 1; for( mask = 0; mask < (1 << N); mask ++) for( k = 0; k < m; k ++) if( f[mask][k] ){ //f[mask][k] 即能否产生这样的情况 long cnt = f[mask][k], pre = -1; //前面已经对a[] 进行排序,这里加入pre后可以去除重复 for(int i = N-1; i >= 0; i --) if(~mask >> i & 1 ){ //mask 中的第i位 即第i个数是否用过 if(a[i] == pre) continue; //去重复 if(a[i] == 0 && mask == 0) continue; //不是很理解 f[ mask | 1 << i][(k*10 + a[i]) % m] += cnt; pre = a[i]; } } cout << f[(1 << N)-1][0] << endl; return 0; }
相关文章推荐
- 【HDU1074 dp状态压缩】Doing Homework 第一道状态压缩dp
- SGU 131.Hardwood floor 状态压缩DP
- 一道状态压缩DP思想题
- POJ 1185 炮兵阵地 (状态压缩dp)
- 状态压缩dp--poj2686
- hoj2662 状态压缩dp
- hdu 2825 ac自动机+状态压缩dp
- poj 1185 炮兵阵地 状态压缩dp
- 洛谷 1052 dp 状态压缩
- C++之路进阶——状态压缩dp(互不侵犯)
- HDU 3247 Resource Archiver(AC自动机+状态压缩dp+最短路BFS)
- poj 3254 Corn Fields(状态压缩dp)
- POJ 1185 炮兵阵地(状态压缩DP)
- 状态压缩DP
- 【连通性状态压缩DP】poj1739
- HDU1074 Doing Homework 状态压缩dp
- POJ-3254 Corn Fields 入门级状态压缩DP
- 【poj2411】Mondriaan's Dream 状态压缩dp
- 【bzoj1087】互不侵犯King 状态压缩dp
- POJ 3254 Corn Fields——状态压缩dp