Vijos-p1154 buy cake (dfs + pruning)

Buy cake

description

Of course everyone will give gifts to the wild cats for their birthdays (cough cough, comrades who didn’t give gifts pay attention!), because they don’t know what to give, and considering other issues such as practicality, we decided to partner up to buy a birthday for the wild cats. cake. Everyone does not know the exact price of the cake to be bought at the end, but only gives an estimate of the price of the cake, that is to say, buy a cake that does not exceed how much money. All OIers take advantage of this: Can the least number of coins be used to make up all the values ​​within the valuation range, so that no matter how much the cake is worth, there is no need to find money...
Now the question arises: for a given n, can it be used? How about the least unequal positive integer to form all the positive integers within n (including n)? If so, how many positive integers are needed at least, and how many different composition methods are there with the least number?

format

Input format

Only one line contains an integer n (1<=n<=1000).

Output format

There are two numbers in a row, the first number is the minimum number required, and the second number is the number of the composition scheme with the minimum number. The two answers are separated by a space.

Example 1

Sample input 1

6

Sample output 1

3 2

limit

Each test point 2s

prompt

Use at least three numbers. There are two methods: 1, 2, 3 and 1, 2, 4.

For 1, 2, 3,
1, 2, 3, 1 +3, 2+3, 1+2+3; for 1, 2, 4, 1, 2, 1+2, 4, 1+4, 2+4.
Portal

Problem solving

Refer to the idea of ​​the big guy: https://blog.csdn.net/a_bright_ch/article/details/83786942
first enumerate what are the situations, and then find the rules

Code

#include <algorithm>
#include <cmath>
#include <iostream>
#include <string>
using namespace std;
const int maxn = 1002;

int len, ans, n;

void dfs(int k, int maxx, int sum) {
    
    
    // k为dfs树层数, maxx为最大的是(最后的数, 当前数), sum为和

    // 若不前剪枝, 会超时
    // if (k == len) {
    
    
    //     if (n <= sum) ans++;
    //     return;
    // }

    if (k == len) {
    
    
        // ans += (sum * 2 + 1) - (n - 1);
        int num = sum - maxx + 1;  //下一节点的孩子数

        //下面给出下一节点的sum的范围
        // sum + maxx + 1 <= newsum <= 2 * sum + 1;

        if (n <= 2 * sum + 1) {
    
      // n <= newsum
            if (n <= sum + maxx + 1)
                ans += num;	//sum - maxx + 1
            else
                ans += num - (n - sum - maxx - 1);	//2 * sum + n - 2
        }
        return;
    }
    for (int i = maxx + 1; i <= sum + 1; i++) dfs(k + 1, i, sum + i);
}

int main() {
    
    
    cin >> n;
    len = (int)log2(n) + 1;

    dfs(1, 0, 0);  // maxx, sum都是上一节点的值
    cout << len << " " << ans << endl;
    system("pause");
    return 0;
}

Timeout code

#include <algorithm>
#include <cmath>
#include <iostream>
#include <string>
using namespace std;
const int maxn = 1002;
int dp[maxn][maxn];

int len, ans, n;

void dfs(int k, int maxx, int sum) {
    
    
    // k为dfs树层数, maxx为最大的是(最后的数, 当前数), sum为和
    if (k == len) {
    
    
        if (n <= sum) ans++;
        return;
    }

    for (int i = maxx + 1; i <= sum + 1; i++) {
    
    
        dfs(k + 1, i, sum + i);
    }
}

int main() {
    
    
    cin >> n;
    len = (int)log2(n) + 1;
    dfs(1, 1, 1);
	cout << len << " " << ans << endl;

    return 0;
}

Guess you like

Origin blog.csdn.net/qq_45349225/article/details/109544948