バックソートへの出力のサブセットに前記ビット操作の以前の使用、本明細書で使用される方法。
バック考えると、私の理解では、次のとおりです。
溶液は、ツリーまたはグラフとしてすべてのケースを変換し、その後、原則深さ優先トラバースすべてのケースを解決します。
この問題は、制約の様々な負担になりますので、もちろん、私たちは枝をトラバース減らすためにこれらの制約を使用することができます。
実際には、と言って、ここではより多くの有名なの順列と組み合わせを見て0-1ナップザック問題、ナップザック問題は後です。
私たちは、現在の数字は、我々は、このようなツリーを描くことができ、現在のデジタルプレゼンスを示すために1によって、存在しない表現するために0を使用して、まだ、[6,7,8]配列であることを前提としています。
本明細書で使用する場合、フォーカスバックトラック関数を生成するマークに対応する再帰フラグ:
#include <stdio.h>
int x[] = {6,7,8}; // 需要排列的数组
int y[] = {0,0,0}; // 存放flag标记
int level = 3; // 有3个数字需要进行排列,对应的就需要排3层
void show()
{
for (int i=0; i<level; i++)
{
printf("flag : %d ", y[i]);
}
printf("\n");
}
void backtrack (int t)
{
if (t == level) // 当遍历深度等于level的时候,说明遍历完成,得到一组完整的flag标记
show();
else
for (int i=0;i<=1;i++) // 这里先生成0标记,再生成1标记
{
y[t]=i; // 记录当前层是否存在,0存在,1不存在
backtrack(t+1); // 递归遍历下一层,这里可以根据题目限制来判断是否需要继续下一层的遍历,可以减少遍历次数
}
}
int main(void)
{
backtrack(0);
return 0;
}
输出结果为:
0 0 0
0 0 1
0 1 0
0 1 1
1 0 0
1 0 1
1 1 0
1 1 1
だから、それを制限し、基本的な考え方を使用する方法についてバックトラック?
例えば、私は価格が8元、5元、2元、10元、である、三つの項目があり、10ドルを持っている
どのような法律を購入することができ、この10ドルは、頼みますか?
ここで限界の存在がある:合計が10を超えることはできません。
#include <stdio.h>
#define TOTAL 10 // 总数最多为10
int x[] = {8,5,2,10}; // 价格
int y[] = {0,0,0,0};
int level = 4;
void show()
{
int n=0;
for (int i=0; i<level; i++) // 计算总价格是否超过10
{
n += y[i] * x[i];
}
if (TOTAL < n)
{
return;
}
for (int i=0; i<level; i++) // 这里直接打印符合条件的价格
{
printf("%d ", y[i]*x[i]);
}
printf("\n");
}
void backtrack (int t)
{
if (t == level)
show();
else
for (int i=0;i<=1;i++)
{
y[t]=i;
int n = 0;
for (int j=0; j<t; j++) // 这里先计算一下当前价格是多少
{
n = y[j] * x[j];
}
if (TOTAL > n) // 如果当前价格已经超了,就不需要再递归下一层(因为不论下一层是否存在,总价格必然会超),否则继续递归
backtrack(t+1);
}
}
int main()
{
backtrack(0);
return 0;
}
结果为:
0 0 0 0
0 0 0 10
0 0 2 0
0 5 0 0
0 5 2 0
8 0 0 0
8 0 2 0