POJ 1564 Sum It Up

7 篇文章 0 订阅

题目点我
简单的深度优先搜索,由于搜索树同一层中同样的数只要试一次,有一点判断重复的小技巧。
没加剪枝也16ms水过,等打球回来看看有哪能优化的。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define maxn 15
int t, n, nTotalSum;
int nNum[maxn], nPath[maxn];
bool bUsed[maxn];

bool dfs(int nSum, int nCurIdx, int nCnt){
    if((nSum == 0) && (nCurIdx < n)){
        for(int i = 0; i < nCnt; i++){
            printf("%d", nNum[nPath[i]]);
            if(i == nCnt - 1)
                printf("\n", nPath[i]);
            else
                printf("+", nPath[i]);
        }
        return true;
    }
    bool bSolvedOnce = false, bSolved = false;
    for(int i = nCurIdx; i < n; i++){
        if((bUsed[i] == false) && (nNum[i] <= nSum)){
            //判断重复的方法:和前一个数相等时,前一个数如果标记已使用,说明这个数是在(搜索树的)下一层用,不能跳过
            //              如果前一个数标记未使用,说明这个数要取代前一个数在同一层使用,需要跳过
            if((nNum[i - 1] == nNum[i]) && (bUsed[i - 1] == false) && (i > 0))
                continue;
            bUsed[i] = true;
            nPath[nCnt] = i;
            bSolvedOnce = dfs(nSum - nNum[i], i, nCnt + 1);
            bUsed[i] = false;
            nPath[nCnt] = -1;
        }
        bSolved = bSolved || bSolvedOnce;
    }
    return bSolved;
}

int main(){
    while(scanf("%d %d", &t, &n) != EOF){
        if((t == 0) && (n == 0))
            break;
        nTotalSum = 0;
        for(int i = 0; i < n; i++){
            scanf("%d", &nNum[i]);
            nTotalSum += nNum[i];
        }
        memset(bUsed, false, sizeof(bUsed));
        memset(nPath, -1, sizeof(nPath));
        printf("Sums of %d:\n", t);
        bool nSolved = dfs(t, 0, 0);
        if(nSolved == false)
            printf("NONE\n");
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值