符号三角形的回溯算法(王晓东算法分析例题)
来源:互联网 发布:钓鱼软件app 编辑:程序博客网 时间:2024/06/02 01:06
题目: 下面都是“-”。 下图是由14个“+”和14个“-”组成的符号三角形。2个同号下面都是“+”,2个异号下面都是“-”。
+ + - + - + +
+ - - - - +
- + + + -
- + + -
- + -
- -
+
在一般情况下,符号三角形的第一行有n个符号。符号三角形问题要求对于给定的n,计算有多少个不同的符号三角形,使其所含的“+”和“-”的个数相同。
思路:我们首先要遍历第一行的所有情况(为了简化问题,我们用0代表+,1代表-,这样根据异或的规则,正好满足题意,又方便了计数)。
注意这里要有剪枝,通过观察我们发现,满足条件的所有三角形中除了初始的3个字符的三角形,其他所有满足结果要求的子三角形中,+和-的个数都是相同的,
这样我们进行剪枝,不等的直接return。另外一个是要特判初始的总数,奇数肯定是不行的。然后注意回溯的时候对sum值进行修改。
剩下的就是dfs的功底了。
#include<iostream>#include<string>#include<cstring>#include<algorithm>using namespace std;int n,half,ans,sum;int s[100][100];void dfs(int t,int sum){if(sum>half||t*(t-1)/2-sum>half)//已经算出的子树不满足,剪枝 return ;if(t>n)//满足要求,相等 { ans++; /* 输出满足条件的矩阵 for(int i=1;i<=n;i++) { for(int j=1;j<=n;j++) cout<<s[i][j]; cout<<endl; } cout<<endl;*/ return ;}for(int i=0;i<2;i++){s[1][t]=i;for(int j=2;j<=t;j++){s[j][t-j+1]=s[j-1][t-j+1]^s[j-1][t-j+2];//递推子树 sum+=s[j][t-j+1];}dfs(t+1,sum+i);for(int j=2;j<=t;j++)//回溯时取消上一次的赋值 sum-=s[j][t-j+1];}} int main(){//n为输入的第一行的个数 while(cin>>n){ans=0,sum=0;half=n*(n+1)/2;memset(s,0,sizeof(s));if(half%2!=0)//总数是奇数直接判0 {cout<<0<<endl;}else{half/=2;//总数的一半 dfs(1,0);cout<<"满足条件的三角形的个数是:"<<endl; cout<<ans<<endl;}}return 0;}
1 0
- 符号三角形的回溯算法(王晓东算法分析例题)
- 符号三角形问题(回溯)-算法设计与分析
- 算法分析与设计回溯法之符号三角形
- 回溯算法及例题
- 回溯算法的常见例题之《迷宫》
- 算法java实现--回溯法--符号三角形问题
- 算法设计_回溯法_符号三角形问题
- C++搜索与回溯算法之符号三角形
- 符号三角形问题;回溯算法;子集树问题;时间复杂度O(2的n次方);
- 算法 符号三角形问题
- 0028算法笔记——【回溯法】批作业调度问题和符号三角形问题
- 0028算法笔记——【回溯法】批作业调度问题和符号三角形问题
- 回溯法-符号三角形
- 符号三角形 回溯法
- 回溯算法中彩票生成算法的分析
- 算法设计与分析例题
- 算法分析之回溯法
- 符号三角形问题 回溯法
- 设置剪贴板内容
- Java-----16、类加载和反射
- 为什么构造函数不能为虚函数
- HAL code debug
- 仿新浪微博IOS客户端(v5.2.8)——下拉菜单栏的实现
- 符号三角形的回溯算法(王晓东算法分析例题)
- Android开发-----NDK开发中的一些常见错误及解决办法
- C语言的结构与联合
- 18.自定义键盘 toolbar的barTintColor UIBarButtonItem的使用 datePick使用
- C 语言状态机编程-去掉代码注释
- xUtils 中的BitmapUtils 全面注释
- sql 的性能优化
- xUtils 中的BitmapUtils 全面注释
- hdu5228 ZCC loves straight flush(模拟)