2 月 6 日算法练习- 深度优先搜索

砝码承重

【问题描述】

    你有一架天平和 N 个砝码,这 N 个砝码重量依次是 W1,W2,...,WN。

    请你计算一共可以称出多少种不同的正整数重量?

    注意砝码可以放在天平两边。

【输入格式】

    输入的第一行包含一个整数 N。

    第二行包含 N 个整数:W1,W2,W3,...,WN。

【输出格式】

    输出一个整数代表答案。

【样例输入】

    3

    1 4 6

【输出样例】

    10

【样例说明】

    能称出的 10 种重量是:1、2、3、4、5、6、7、9、10、11。

    1 = 1;

    2 = 6 − 4 (天平一边放 6,另一边放 4);

    3 = 4 − 1;

    4 = 4;

    5 = 6 − 1;

    6 = 6;

    7 = 1 + 6;

    9 = 4 + 6 − 1;

    10 = 4 + 6;

    11 = 1 + 4 + 6。

【评测用例规模与约定】

    对于 50% 的评测用例,1≤N≤15。

    对于所有评测用例,1≤N≤100,N 个砝码总重不超过 100000。

思路:可以用 DFS,每个砝码有三种状态,放左边,放右边或都不放,时间复杂度是 O^3,N 为 15,O^3为 10^7 左右,可以过 50% 的数据。

#include
using namespace std;
const int M = 1e5+10,N = 1e2+5;
int n,ans,w[N],vis[M];

void dfs(int i,int left, int right){
    if(i>n){
        vis[max(left,right)-min(left,right)]=1;
        return;
    }
    dfs(i+1,left+w[i],right);
    dfs(i+1,left,right+w[i]);
    dfs(i+1,left,right);
}

int main( ){
    cin>>n;
    for(int i=1;i<=n;i++)cin>>w[i];
    dfs(1,0,0);
    for(int i=1;i<M;i++)if(vis[i])ans++;
    cout<<ans<<'\n';
    return 0;
}

你可能感兴趣的:(算法,深度优先,算法,图论)