[洛谷P2396]yyy loves Maths VII $\&$ [CF327E]Axis Walking

本文深入解析状态压缩动态规划的原理与应用,通过具体题目示例,展示如何利用位运算进行子集生成及状态转移,特别关注在特定条件下的状态跳转优化,适用于竞赛编程与算法设计的学习者。

这道题是一个状压动归题。子集生成,每一位表示是否选择了第$i$个数。

转移:$f[S] = \sum f[S-\{x\}]$且$x\in S$,当该子集所有元素的和为$b_1$或$b_2$时不转移。

初始化:$f[\{\}]=1$,其他为$0$。

目标:$f[全集]$。

注意常数即可。

 1 #include <bits/stdc++.h>
 2 
 3 using namespace std;
 4 
 5 #define re register
 6 #define rep(i, a, b) for (re int i = a; i <= b; ++i)
 7 #define repd(i, a, b) for (re int i = a; i >= b; --i)
 8 #define maxx(a, b) a = max(a, b);
 9 #define minn(a, b) a = min(a, b);
10 #define LL long long
11 #define inf (1 << 30)
12 
13 inline int read() {
14     int w = 0, f = 1; char c = getchar();
15     while (!isdigit(c)) f = c == '-' ? -1 : f, c = getchar();
16     while (isdigit(c)) w = (w << 3) + (w << 1) + (c ^ '0'), c = getchar();
17     return w * f;
18 }
19 
20 int f[1 << 24], dis[1 << 24], n, m, b[3];
21 const int Mod = 1000000007;
22 
23 #define mod(x) (x>=Mod?x-Mod:x)
24 
25 int main() {
26     n = read();
27     rep(i, 1, n) dis[1<<(i-1)] = read();
28     m = read();
29     rep(i, 1, m) b[i] = read();
30     f[0] = 1;
31     rep(i, 1, (1<<n)) {
32         dis[i] = dis[i&(i-1)] + dis[i&-i];
33         if (dis[i] == b[1] || dis[i] == b[2]) continue;
34         for (register int x = i; x; x &= (x-1)) f[i] = mod(f[i]+f[i^x&-x]);
35     }
36     printf("%d", f[(1<<n)-1]);
37     return 0;
38 }

 

转载于:https://www.cnblogs.com/ac-evil/p/10350879.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值