符号三角形问题—回溯算法—java实现
问题描述:
下图是由14个“+”和14个“-”组成的符号三角形。2个同号下面都是“+”,2个异号下面都是“-”:
符号三角形第一行有n个符号,符号三角形问题要求对于给定的n,计算有多少个不同的符号三角形,使其所含的“+”和“-”的个数相同。
解题思路:
1、不断改变第一行的每个符号,搜索符合条件的解,可以使用递归回溯。
为了便于运算,设+ 为0,- 为1,这样可以使用异或运算符表示符号三角形的关系:
++为+即0^0=0, --为+即1^1=0, +-为-即0^1=1, -+为-即1^0=1
2、因为两种符号个数相同,可以对题解树剪枝
当所有符号总数为奇数时无解,当某种符号超过总数一半时无解
算法设计:
在符号三角形的第一行的前i个符号x[1:i]确定后,就确定了一个由i*(i+1)/2个符号组成的符号三角形。
下一步确定了x[1:i]的值后,只要在前面确定的符号三角形的右边加一条边,就可以扩展为x[1:i]所对应的符号三角形。
在回溯法搜索过程中可用当前符号三角形所包含的“+”号个数与“-”号个数均不超过n*(n-1)/4作为可行性约束,用于剪去不满足约束条件的子树。
代码:
需要的数据:
static int n;//第一行的符号个数static int half;//n*(n+1)/4static int count;//当前“+”或者“-”的个数static int[][] p;//符号三角形矩阵static long sum;//已找到的符号三角形的个数
初始化及计算:
public static float Compute(int nn) {n = nn;count = 0;sum = 0;half = (n*(n+1))>>1;if((half>>1)<<1 != half) {return 0;}half = half>>1;p = new int[n+1][n+1];backtrack(1);return sum;}
回溯算法1(仅用于计算行数或者列数为n的符号三角形的总数,没有显示符号三角形的功能,但是是核心代码):
public static void backtrack01(int t) {if(count>half || (t*(t-1)/2-count > half)) {//对题解树的剪枝return;}if(t>n) {sum++;//符号三角形的总数目+1}else {//每个位置都有两种情况0,1for(int i = 0;i<2;i++) {p[1][t] = i;count += i;//对"-"个数进行技术,为了进行剪枝操作//接下来绘制其余的n-1行for(int j = 2;j<=t;j++) {//通过异或的方式求其余行数的放置方式p[j][t-j+1] = p[j-1][t-j+1]^p[j-1][t-j+2];count += p[j][t-j+1]; }backtrack01(t+1);//恢复现场for(int j = 2;j<=t;j++) {count -= p[j][t-j+1];}count -= i;}}}
回溯算法2(具备打印符号三角形的功能):
public static void backtrack(int t) {if((count>half)||(t*(t-1)/2-count > half)) //对题解树的剪枝return;if(t>n) {sum++;//打印符号三角形for(int i =1;i<=n;i++) {for(int k = 1;k<i;k++) {System.out.print(" ");}for(int j =1;j<=n;j++) {if(p[i][j] == 0 && j<=n-i+1) {System.out.print("+" + " ");}else if(p[i][j] == 1 && j<=n-i+1) {System.out.print("-" + " ");}else {System.out.print(" ");}}System.out.println();}System.out.println();}else {//每个位置都有两种情况0,1for(int i =0;i<2;i++) {p[1][t] = i;count += i;//计算“-”的个数//接下来绘制其余的n-1行for(int j = 2;j<=t;j++) {//通过异或的方式求其余行数的放置方式p[j][t-j+1] = p[j-1][t-j+1]^p[j-1][t-j+2];count += p[j][t-j+1];}backtrack(t+1);//恢复现场for(int j =2;j<=t;j++) {count -= p[j][t-j+1];}count -= i;}}}
完整代码:
package tri;public class TRAN {static int n;//第一行的符号个数static int half;//n*(n+1)/4static int count;//当前“+”或者“-”的个数static int[][] p;//符号三角形矩阵static long sum;//已找到的符号三角形的个数public static float Compute(int nn) {n = nn;count = 0;sum = 0;half = (n*(n+1))>>1;if((half>>1)<<1 != half) {return 0;}half = half>>1;p = new int[n+1][n+1];backtrack(1);return sum;}/*** 算法1* @param t*//*public static void backtrack01(int t) {if(count>half || (t*(t-1)/2-count > half) {//对题解树的剪枝return;}if(t>n) {sum++;//符号三角形的总数目+1}else {//每个位置都有两种情况0,1for(int i = 0;i<2;i++) {p[1][t] = i;count += i;//对"-"个数进行技术,为了进行剪枝操作//接下来绘制其余的n-1行for(int j = 2;j<=t;j++) {//通过异或的方式求其余行数的放置方式p[j][t-j+1] = p[j-1][t-j+1]^p[j-1][t-j+2];count += p[j][t-j+1]; }backtrack01(t+1);//恢复现场for(int j = 2;j<=t;j++) {count -= p[j][t-j+1];}count -= i;}}}*/public static void backtrack(int t) {if((count>half)||((t*(t-1)/2-count > half)) //对题解树的剪枝return;if(t>n) {sum++;//打印符号三角形for(int i =1;i<=n;i++) {for(int k = 1;k<i;k++) {System.out.print(" ");}for(int j =1;j<=n;j++) {if(p[i][j] == 0 && j<=n-i+1) {System.out.print("+" + " ");}else if(p[i][j] == 1 && j<=n-i+1) {System.out.print("-" + " ");}else {System.out.print(" ");}}System.out.println();}System.out.println();}else {//每个位置都有两种情况0,1for(int i =0;i<2;i++) {p[1][t] = i;count += i;//计算“-”的个数//接下来绘制其余的n-1行for(int j = 2;j<=t;j++) {//通过异或的方式求其余行数的放置方式p[j][t-j+1] = p[j-1][t-j+1]^p[j-1][t-j+2];count += p[j][t-j+1];}backtrack(t+1);//恢复现场for(int j =2;j<=t;j++) {count -= p[j][t-j+1];}count -= i;}}}public static void main(String[] args) {// TODO Auto-generated method stubfloat SUM = Compute(4); System.out.print("总数: " + SUM);}}
以行数为4的符号三角形为例,显示输出如下:
符号三角形问题—回溯算法—java实现相关推荐
- 0-1背包问题—回溯算法—java实现
0-1背包问题 [问题描述] 有n种可选物品1,-,n ,放入容量为c的背包内,使装入的物品具有最大效益. 表示 n :物品个数 c :背包容量 p1,p2, -, pn:个体物品效益值 w1,w2, ...
- java符号三角形问题_实验四 回溯算法和分支限界法 符号三角形问题
基本题一:符号三角形问题 一.实验目的与要求 1.掌握符号三角形问题的算法: 2.初步掌握回溯算法: 二.实验题图 下面都是"-".下图是由14个"+"和14个 ...
- 符号三角形问题(回溯)
[cpp] view plaincopy /*回溯法解符号三角形问题 问题描述: 如下图是由14个"+"和14个"-"组成的符号三角形, 2个同号下面都是&qu ...
- java 符号三角形_算法java实现--回溯法--符号三角形问题
符号三角形问题的java实现(回溯法) 具体问题描述以及C/C++实现参见网址 http://blog.csdn.net/liufeng_king/article/details/8764319 /* ...
- 算法设计与分析——回溯法——符号三角形问题
#include<iostream> using namespace std;class Triangle{public:void Backtrack(int t);int n;//第一行 ...
- 005-3算法笔记【回溯】符号三角形
问题 符号三角形的 第1行有n个由"+"和"-"组成的符号 ,以后每行符号比上行少1个,2个同号下面是"+",2个异 号下面是"- ...
- 符号三角形问题(Java)
符号三角形问题(Java) 文章目录 符号三角形问题(Java) 1. 前置介绍 2.算法设计 3.程序代码 4.算法效率 5.参考资料 1. 前置介绍 符号三角形定义 如下图所示,符号三角形是由14 ...
- 8皇后以及N皇后算法探究,回溯算法的JAVA实现,非递归,数据结构“栈”实现
是使用递归方法实现回溯算法的,在第一次使用二维矩阵的情况下,又做了一次改一维的优化 但是算法效率仍然差强人意,因为使用递归函数的缘故 下面提供另一种回溯算法的实现,使用数据结构"栈" ...
- [Leetcode][第81题][JAVA][N皇后问题][回溯算法]
[问题描述][困难] [解答思路] 1. 主副对角线列 标记 复杂度 import java.util.ArrayDeque; import java.util.ArrayList; import j ...
最新文章
- MYSQL执行计划EXPLAIN
- HTML简介及常用标签介绍
- python socket原理 及socket如何使(tcp udp协议)
- 姆町网络验证带壳内存取密钥
- SpringCloud服务器服务注册在Euraka上,访问IP地址问题
- c编程语言外文翻译及原文,外文翻译--基于ST语言(结构化文本语言)可编程控制器(中文)...
- ruhe调整计算机色温,显示器色温怎么调节
- Java中修饰变量和方法的关键字总结分析
- 正襟危坐说--操作系统(伍):进程间通信
- 如何给运行中的docker容器增加映射端口
- 如何看待腾讯云电子签呢?
- 北斗短报文和北斗定位入门篇
- Oracle数据库Timestamp数据差值计算Sql语句
- gentoo virtual couldnt download
- 讲讲自己一天入门Python的一些心得
- 施密特(smit)触发器
- 同济大学高等数学上册电子版_函数的凹凸性漫谈|高等数学漫步(二)
- CorelDRAWX4的C++插件开发(四十一)纯C++插件开发(5)实现六个纯虚函数
- 列车车次查询系统php源码,火车票务系统源代码(含数据库)
- java 按钮 事件_Java给按钮添加事件
热门文章
- 微带线宽与承受功率的关系
- 硬盘模式兼容性问题不难解决,我们将新电脑的主板设置调整为IDE模式,进入操作系统,修改注册表让操作系统和AHCI匹配:
- 用Python创作的搜狗输入法刷字数神器(装逼必备)
- 【Mysql】MySQL修改用户host的方法整理
- 基于uniapp校园帮外卖跑腿快递代拿平台设计【还可发布到小程序和HTML5】
- Ubuntu20.04.3 + opengrok1.7.25 + tomcat10.0.14安装
- Android版本中蓝牙简介
- 如何将D3.js的强交互延续到Python中?
- java时间解析错误_java.lang.IllegalArgumentException:解析错误-日期格式错误?
- View和XenDesktop到底谁更简单 Part II