Backtracking C++

Backtracking C++

本文关键字:C++ Backtracking      更新时间:2023-10-16

我有以下问题:

有多少不同的票号,n个数字加起来就是"answers"?

For example: 
How many different ticket numbers are there with 3 digits that add up to 4?
There are exactly 15 different such numbers:
004, 013, 022, 031, 040, 103, 112, 121, 130, 202, 211, 220, 301, 310, 400.

我有以下代码:

#include <iostream.h> 
using namespace std;
int n,st[100],ok=0, sum;
void afisare()
{
    int s=0;
    for(int i=0;i<n;i++)
       s=s+st[i];
    if (s==sum)
    {
        for(int i=0;i<n;i++)
            cout<<st[i]<<' ';
        cout<<'n';
        ok++;
    }
}
void back(int k)
{
    int i;
    if(k>n)
       afisare();
    else
       for(i=0;i<10;i++)
       {
        st[k]=i;
        back(k+1);
       }
}
int main()
{
    cout<<"n=";cin>>n;
    cout << "sum= "; cin >> sum;
    back(0);
    cout << endl << endl << ok/10;
    return 0;
}

问题是它把每个解决方案准确地打了10次,我不明白怎么。。。我做错了什么?

如果考虑最基本的情况,这些类型的问题通常最容易调查。为什么不追踪一个数字中有多少个位数的门票?它应该只有一个,对吧(假设数字小于10,否则为0)?好吧,遍历sum=9和n=1:的代码

void back(int k)
{
    int i;
    if(k>n)
       afisare();
    else
       for(i=0;i<10;i++)
       {
        st[k]=i;
        back(k+1);
       }
}

当您用n = 1调用back(0)时,它会注意到0不大于1。因此,它将遍历0到9的所有数字,并将它们相加,然后回调(1)。然后它会注意到,在那个调用中,k是1,等于到n。所以你会有另一个数字附加循环。。。0到10,并将k…现在提升到2。因此,你最终会在两位数上触底。

但是你的和只有n位数,因此是10倍。简而言之:您使用的是比较k>n,而不是k==n

所以你在某种意义上是"亲密的"。但这里还有许多其他需要注意的事情。#include <iostream.h>在现代编译器中不起作用,它应该只是#include <iostream>。全局变量的使用形式很差,固定大小的数组而不是std::vector:也是如此

阵列与矢量:简介的异同

作为第一步,尝试重新思考这个没有全局变量或固定大小数组的程序。