SLE for Spoj BTCK

时间:2018-06-10 17:46:55

标签: c++ algorithm backtracking

嘿,我最近一直在研究这个问题但是无法使用回溯来解决这个问题。

  

问题:您必须使用Backtracking解决以下问题。   给你一个10个正整数的序列n1,n2,n3,...   ,n9,n10和正值K.

     

要解决这个问题,你需要打印一个排列a1,a2,a3,   ...,数字{0,1,2,3,4,5,6,7,8,9}中的a10,使得a1 * n1 + a2   * n2 + a3 * n3 + ... + a10 *n10≤K

     

在所有根据问题解决问题的排列中   上面的描述,打印按字典顺序最小的。

Link to question

我的代码如下:

#include <algorithm>
#include <iostream>

#define ll long long
#define forn(i,a,b) for(int i = a; i < b; i++)

using namespace std;

ll k;
bool solved = 0; // Tells if we have found a solution or not.
int ans[10];  // Will contain the final sequence of ai s
int arr[10];  // Contains the numbers provided in the question. For this example arr[] = {1,2,3,4,5,6,7,8,9,10}
bool vis[10]={false}; // Denotes if the value ai(see the question) has been used or not

void print();

bool solve(int n, ll sum, int movei)  // n = 10 , movei => which number we have to assign ai to.
{
    if(sum > k) {
            return false;   // Backtrack
    }
    if(movei == n)
    {
        return sum<=k;
    }
    forn(i,movei,n)
    {
        forn(j,0,10)
        {
            if(vis[j]) continue;
            ans[i]=j;
            vis[j]=1;
            if(solve(n, sum + arr[i]*j, movei+1)) return true; // If we found a solution return true
            vis[j]=0;
        }
    }
    return false; // We could not find any solution at all.
}

void print()
{
    forn(i,0,10)
    cout << ans[i] << " ";
}

int main()
{
    int t;         // Number of test cases
    //cin >> t;
    t = 1;
    while(t--)
    {
        forn(i,0,10) arr[i] = i+1; //cin >> arr[i];
        cin >> k;
        if(solve(10,0LL,0)) print();
        else cout << -1;
        cout<<endl;
    }
}

方法
1)检查所有路径
2)如果你找到一个解决方案,那么这将是按字典顺序最小的顺序,所以返回true,意味着找到解决方案
3)继续寻找解决方案。
4)如果你在任何路径中都找不到解决方案,那么返回false,意味着无法找到解决方案,在哪种情况下我打印-1。

我该如何解决这个问题。我一直在努力工作,但不能想其他任何事情。

1 个答案:

答案 0 :(得分:0)

感谢@juvian和@PaulMcKenzie的回复。代码如下,

#include <algorithm>
#include <iostream>

using namespace std;

void print(int a[], int n)
{
    for(int i = 0; i < n; i++)
        cout << a[i] << " ";
}

int main()
{
    int test;
    cin >> test;
    int n[10], a[10], k;
    while(test--)
    {
        for(int i = 0; i < 10; i++)
        cin >> n[i];
        cin >> k;

        bool solved = false;

        for(int i = 0; i < 10; i++) a[i] = i;

        do
        {
            int k1 = 0;
            for(int i = 0; i < 10; i++)
            {
                k1 += n[i]*a[i];
            }
            if(k1 <= k)
            {
                solved = true;
                print(a, 10);
                break;
            }
        }while(next_permutation(a, a+10));

        if(!solved) cout << -1;
        cout << endl;
    }
    return 0;
}