POJ--3187 Backward Digit Sums(暴搜/减枝)

发布时间 2023-03-25 19:37:46作者: 57one

记录
5:30 2023-3-25

http://poj.org/problem?id=3178

reference:《挑战程序设计竞赛(第2版)》第二章练习题索引 p135

Description

FJ and his cows enjoy playing a mental game. They write down the numbers from 1 to N (1 <= N <= 10) in a certain order and then sum adjacent numbers to produce a new list with one fewer number. They repeat this until only a single number is left. For example, one instance of the game (when N=4) might go like this:

3   1   2   4

  4   3   6

    7   9

     16

Behind FJ's back, the cows have started playing a more difficult game, in which they try to determine the starting sequence from only the final total and the number N. Unfortunately, the game is a bit above FJ's mental arithmetic capabilities.

Write a program to help FJ play the game and keep up with the cows.

Input

Line 1: Two space-separated integers: N and the final sum.

Output

Line 1: An ordering of the integers 1..N that leads to the given sum. If there are multiple solutions, choose the one that is lexicographically least, i.e., that puts smaller numbers first.

Sample Input

4 16

Sample Output

3 1 2 4

Hint

Explanation of the sample:

There are other possible sequences, such as 3 2 1 4, but 3 1 2 4 is the lexicographically smallest.

暴搜,用stl中的next_permutation生成组合数(自己写也可以 类似于dfs的思路 输出组合数)
减枝的思路:这里很简单,next_permutation生成的序列大小是从小到大的(前提:使用的序列是自然数序列1 2 3 4 5 ... n),自己写组合数生成的话应该也是生成从小到大的,所以生成的第一个满足条件的就是最小的那个(实测,如果生成全部的序列会TLE)

#include<cstdio>
#include<iostream>
#include<algorithm>
#define MAX_N 20
using namespace std;
typedef long long ll;
typedef unsigned int uint;
const int INF = 0x3f3f3f3f;

uint N, M;
uint num[MAX_N + 1] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
uint result[MAX_N + 1];

uint sum() {
    uint temp[N];
    uint temp_N = N;
    memcpy(temp, num, sizeof(temp));
    while (temp_N > 1) {
        for(uint i = 0; i < temp_N - 1; i++) {
            temp[i] = temp[i] + temp[i + 1];
        }
        temp_N--;
    }
    return temp[0];
}

void print() {
    if(N == M == 1) {
        result[0] = 1;
    }
    for(int i = 0 ; i < N; i++) {
        if(i != N-1) {
            printf("%d ", result[i]);
        } else {
            printf("%d\n", result[i]);
        }
    }
}

void solve() {
    fill(result, result + MAX_N + 1, INF);
    do {
        uint total = sum();
        if(total == M) {
            // for(int i = 0; i < N; i++) {
            //     if(num[i] > result[i]) {
            //         break;
            //     } else if(num[i] == result[i]){
            //         continue;
            //     } else {
            //         memcpy(result, num, sizeof(result));
            //         break;
            //     }
            // }
            memcpy(result, num, sizeof(result));
            break;
        }
    } while (next_permutation(num, num + N));
    print();
}

int main() {
    while (~scanf("%d%d", &N, &M)) {
        solve();
    }
}