POJ_1564 Sum It Up(DFS)

Description

Given a specified total t and a list of n integers, find all distinct sums using numbers from the list that add up to t. For example, if t = 4, n = 6, and the list is [4, 3, 2, 2, 1, 1], then there are four different sums that equal 4: 4, 3+1, 2+2, and 2+1+1. (A number can be used within a sum as many times as it appears in the list, and a single number counts as a sum.) Your job is to solve this problem in general.
Input

The input will contain one or more test cases, one per line. Each test case contains t, the total, followed by n, the number of integers in the list, followed by n integers x 1 , … , x n . If n = 0 it signals the end of the input; otherwise, t will be a positive integer less than 1000, n will be an integer between 1 and 12 (inclusive), and x 1 , … , x n will be positive integers less than 100. All numbers will be separated by exactly one space. The numbers in each list appear in nonincreasing order, and there may be repetitions.
Output

For each test case, first output a line containing Sums of', the total, and a colon. Then output each sum, one per line; if there are no sums, output the lineNONE’. The numbers within each sum must appear in nonincreasing order. A number may be repeated in the sum as many times as it was repeated in the original list. The sums themselves must be sorted in decreasing order based on the numbers appearing in the sum. In other words, the sums must be sorted by their first number; sums with the same first number must be sorted by their second number; sums with the same first two numbers must be sorted by their third number; and so on. Within each test case, all sums must be distinct; the same sum cannot appear twice.
Sample Input

4 6 4 3 2 2 1 1
5 3 2 1 1
400 12 50 50 50 50 50 50 25 25 25 25 25 25
0 0
Sample Output

Sums of 4:
4
3+1
2+2
2+1+1
Sums of 5:
NONE
Sums of 400:
50+50+50+50+50+50+25+25+25+25
50+50+50+50+50+25+25+25+25+25+25

题目解析:
有一行数字按递减排列,求出所有的组合使数字和为某一个固定值。安照排列顺序从第一个数往后DFS,直到能满足条件。每一次的pos表示当前选择第几位,所以要注意对于该位的数字如果在数列中后一位与前一位相同,就不能计算,否则会重复。
代码实现:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define MAX 1000002
using namespace std;

int T,N;
int sx;
int Times;
int num[MAX];
int save[MAX];
void dfs(int x,int y);
void print();

int main()
{
    while( scanf("%d%d",&T,&N) )
    {
        if( T == 0 && N == 0 )
            break;
        Times = 0; sx = 0;
        memset(num,0,sizeof(num));
        for( int i = 0; i < N; i++ )
            scanf("%d",&num[i]);
        cout<<"Sums of "<<T<<':'<<endl;
        for( int i = 0; i < N; i++ )
        {
            if( i != 0 && num[i] == num[i-1] )
                continue ;
            save[sx] = num[i];
            sx++;
            dfs(i,num[i]);
            sx--;
            save[sx]=0;
        }
        if( Times == 0 )
            cout<<"NONE"<<endl;
    }
    return 0;
}

void dfs(int pos,int sum)
{
    if( sum >= T )
    {
        if( sum == T )
        {
            Times++;
            print();
        }
        return ;
    }
    for( int i = pos+1 ; i < N; i++ )
    {
        if( i-1 != pos && num[i] == num[i-1] )
            continue ;
        save[sx] = num[i];
        sx++;
        dfs(i,sum+num[i]);
        sx--;
        save[sx]=0;
    }
    return ;
}

void print()
{
    for( int i = 0; i < sx; i++ )
    {
        cout<<save[i];
        if( i != sx-1 )
            cout<<'+';
        else
            cout<<endl;
    }
    return ;
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
POJ 1321 排兵布阵问题可以使用 DFS 算法求解。 题目要求在一个 n x n 的棋盘上,放置 k 个棋子,其中每行、每列都最多只能有一个棋子。我们可以使用 DFS 枚举每个棋子的位置,对于每个棋子,尝试将其放置在每一行中未被占用的位置上,直到放置了 k 个棋子。在 DFS 的过程中,需要记录每行和每列是否已经有棋子,以便在尝试放置下一个棋子时进行判断。 以下是基本的 DFS 模板代码: ```python def dfs(row, cnt): global ans if cnt == k: ans += 1 return for i in range(row, n): for j in range(n): if row_used[i] or col_used[j] or board[i][j] == '.': continue row_used[i] = col_used[j] = True dfs(i + 1, cnt + 1) row_used[i] = col_used[j] = False n, k = map(int, input().split()) board = [input() for _ in range(n)] row_used = [False] * n col_used = [False] * n ans = 0 dfs(0, 0) print(ans) ``` 其中,row 代表当前尝试放置棋子的行数,cnt 代表已经放置的棋子数量。row_used 和 col_used 分别表示每行和每列是否已经有棋子,board 则表示棋盘的状态。在尝试放置棋子时,需要排除掉无法放置的位置,即已经有棋子的行和列,以及棋盘上标记为 '.' 的位置。当放置了 k 个棋子时,即可计数一次方案数。注意,在回溯时需要将之前标记为已使用的行和列重新标记为未使用。 需要注意的是,在 Python 中,递归深度的默认限制为 1000,可能无法通过本题。可以通过以下代码来解除限制: ```python import sys sys.setrecursionlimit(100000) ``` 完整代码如下:

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值