利用动态规划将逻辑函数化简到最简形式
来源:互联网 发布:货架重量计算软件 编辑:程序博客网 时间:2024/06/08 13:45
//// Created by Running Photon on 2016-2-29// Copyright (c) 2015 Running Photon. All rights reserved.//#include <algorithm>#include <cctype>#include <cmath>#include <cstdio>#include <cstdlib>#include <cstring>#include <iomanip>#include <iostream>#include <map>#include <queue>#include <string>#include <sstream>#include <set>#include <vector>#include <stack>#define ALL(x) x.begin(), x.end()#define INS(x) inserter(x, x,begin())#define ll long long#define CLR(x) memset(x, 0, sizeof x)using namespace std;const int inf = 0x3f3f3f3f;const int MOD = 1e9 + 7;const int maxn = 1e6 + 10;const int maxv = 1e2 + 10;const double eps = 1e-9;/*设有集合state1和state2state1的01串,如果当前位置是1就表示当前位还没被化简掉,如果是0就表示当前位已经被化简掉state2的01串。如果当前位置是1,就表示他本身,如果是0,就表示取反(就是A和!A)dp[state1][state2]数组存的是当前状态是否存在have[state1][state2]用来记录答案当前状态是否已经被跟高维度(消的元素越多维度越高)利用如果被利用,那么这个状态就可以省略的 记录为0如果没有比他高维的状态利用他,记录为1最后答案就是枚举have的所有可能 并且是1就输出*/int dp[(1 << 10) + 5][(1 << 10) + 5];int have[(1 << 10) + 5][(1 << 10) + 5];int state[(1 << 10) + 5];int n, len;int dfs(int nan, int cur) { ///记忆化操作 if(dp[nan][cur] != -1) return dp[nan][cur]; ///判断当前状态是不是已经是最底层(叶子节点) if(nan == (1 << len) - 1) { if(state[cur]) have[nan][cur] = 1;// printf("cur = %d res = %d\n", cur, state[cur]); return dp[nan][cur] = state[cur]; } ///先初始化当前状态不能被组合出来 int flag = 0; for(int i = 0; i < len; i++) { ///枚举可以消的每一位 if((1 << i) & nan) continue; ///如果为1则表示当前位不能被消 int nnan = nan ^ (1 << i); ///nan 是从nnan状态转移过来的 ///此处模拟消的过程,消的规则就是,只有一位不同 int f1 = dfs(nnan, cur); ///当前状态是否存在 int f2 = dfs(nnan, cur ^ (1 << i)); ///当前位取反后是否存在; if(f1 && f2) { ///为了只输出一种结果,分析可知,当它的右儿子(就是cur ^ (1 << i))和左儿子(cur)都没有被其他的状态吸收的时候,当前状态才有输出价值 if(have[nnan][cur ^ (1 << i)] || have[nnan][cur]) have[nan][cur] = 1; have[nnan][cur] = have[nnan][cur ^ (1 << i)] = 0; ///当前位合法,所以他的两个子状态被吸取 不用输出,have置0// printf("have[%d][%d] = 0\n", nnan, cur, have[nnan][cur]);// printf("have[%d][%d] = %d\n", nan, cur, have[nan][cur]); flag = 1;// return dp[nan][cur] = flag; } } ///返回当前状态是否存在 return dp[nan][cur] = flag;}void print(int i, int j, int& cas) { if(cas++) printf(" + "); for(int k = len - 1; ~k; k--) { if(!((1 << k) & i)) continue; if((1 << k) & j) { printf("%c", 'A' + len - 1 - k); } else printf("!%c", 'A' + len - 1 - k); }}int main() {//#ifdef LOCAL freopen("in.txt", "r", stdin);// freopen("out.txt","w",stdout);//#endif// ios_base::sync_with_stdio(0); ///n表示有n个最小项,len表示有len个元素(此程序处理范围为len <= 10) while(scanf("%d%d", &n, &len) != EOF && n && len) { ///输入最小项个数n和元素个数len ///分别输入n个最小项,0表示非,1表示(默认从左到右是A, B, C...) CLR(state); for(int i = 0; i < n; i++) { int tmp = 0; for(int j = 0; j < len; j++) { int x; scanf("%1d", &x); ///state数组表示输入的状态。 tmp = tmp * 2 + x; }// printf("tmp = %d\n", tmp); state[tmp] = 1; } ///将所有状态初始化为-1,表示未访问过,用来记忆化搜索,减少时间消耗 memset(dp, -1, sizeof dp); ///have 数组初始化为0 CLR(have); ///如果所有元素都被消掉了,那说明是恒成立之类的时间, if(dfs(0, 0)) {printf("result is 1"); continue;} int cas = 0; for(int i = 0; i < 1 << len; i++) { if(have[i][0]) { print(i, 0, cas); } for(int j = i; j; j = (j - 1) & i) { ///二进制枚举子集 if(have[i][j]) { print(i, j, cas); } } } puts(""); } return 0;}
0 0
- 利用动态规划将逻辑函数化简到最简形式
- 动态规划(2):动态规划的三种形式
- 背包问题的动态规划形式解
- Ackmann函数-- 动态规划
- 利用动态规划解题思路
- LA 3720 highway(利用动态规划思想,将复杂度急降,9ms)
- 动态规划入门(讲故事的形式,很棒!)
- 利用动态规划方法求素数
- 记录结果在利用的“动态规划”
- 利用动态规划解决连乘问题
- 利用动态规划解决交叉字符串问题
- 利用动态规划求解01背包问题
- 利用动态规划求解Fibonacci数列
- 动态规划之背包问题之逻辑(无代码)
- 利用Data URL将小图片生成数据流形式
- 如何利用matlab将模糊逻辑转化为查询表
- 如何利用matlab将模糊逻辑转化为查询表
- 如何利用matlab将模糊逻辑转化为查询表
- 不要24小时都想念同一个人_52jdss 经典说说
- android 零碎知识点收集
- Mac OSX 10.11.1+ 安装 Cocoapods
- Day8:IDEA 开发spark
- Java程序的工作方式
- 利用动态规划将逻辑函数化简到最简形式
- ruby warrior intermediate个人攻略(可能会更新
- POJ 3286 How many 0's?(数位dp)
- js作用域
- [LeetCode] Same Tree
- 第一行代码-10.3 解析XML数据格式
- html设置按钮背景颜色与背景图片一样,即设置按钮背景透明
- bzoj3524【POI2014】Couriers
- 数据与数据结构