• [UVALive 6661 Equal Sum Sets] (dfs 或 dp)


    题意:

    求从不超过 N 的正整数其中选取 K 个不同的数字,组成和为 S 的方法数。

    1 <= N <= 20  1 <= K<= 10  1 <= S <= 155


    解题思路:

      DFS:

      因为N,K。S的范围非常小。直接DFS就可以。

    /*
    ID: wuqi9395@126.com
    PROG:
    LANG: C++
    */
    #include<map>
    #include<set>
    #include<queue>
    #include<stack>
    #include<cmath>
    #include<cstdio>
    #include<vector>
    #include<string>
    #include<fstream>
    #include<cstring>
    #include<ctype.h>
    #include<iostream>
    #include<algorithm>
    #define INF (1<<30)
    #define PI acos(-1.0)
    #define mem(a, b) memset(a, b, sizeof(a))
    #define For(i, n) for (int i = 0; i < n; i++)
    typedef long long ll;
    using namespace std;
    int n, k, s;
    int cnt = 0;
    void dfs(int sum, int x, int depth) {
        if (sum > s) return ;
        if (k - 1 == depth) {
            if (sum == s) cnt++;
            return ;
        }
        for (int i = x + 1; i <= min(n, s - sum); i++) dfs(sum + i, i, depth + 1);
    }
    int main () {
        while(scanf("%d%d%d", &n, &k, &s)) {
            if (n + k + s == 0) break;
            cnt = 0;
            for (int i = 1; i <= n; i++) {
                dfs(i, i, 0);
            }
            printf("%d
    ", cnt);
        }
    }


      DP:

      

    dp[i][j][k] = dp[i - 1][j][k] + dp[i - 1][j - i][k - 1] //dp[i][j][k]表示从不超过i的数字中选取k个数和为j的方法数。

    /*
    ID: wuqi9395@126.com
    PROG:
    LANG: C++
    */
    #include<map>
    #include<set>
    #include<queue>
    #include<stack>
    #include<cmath>
    #include<cstdio>
    #include<vector>
    #include<string>
    #include<fstream>
    #include<cstring>
    #include<ctype.h>
    #include<iostream>
    #include<algorithm>
    #define INF (1<<30)
    #define PI acos(-1.0)
    #define mem(a, b) memset(a, b, sizeof(a))
    #define For(i, n) for (int i = 0; i < n; i++)
    typedef long long ll;
    using namespace std;
    int dp[22][160][11];
    int n, k, s;
    int main () {
        dp[0][0][0] = 1;
        for (int i = 1; i <= 20; i++) {
            for (int j = 0; j <= 155; j++) {
                for (int k = 0; k <= 10; k++) {
                    dp[i][j][k] = dp[i - 1][j][k];
                    if (k > 0 && j >= i) dp[i][j][k] += dp[i - 1][j - i][k - 1];
                }
            }
        }
        while(scanf("%d%d%d", &n, &k, &s), n || k || s) printf("%d
    ", dp[n][s][k]);
    }


      

  • 相关阅读:
    Unity3D 利用C#实现简单的代理模式Delegate(委托)
    代码删除文件夹,小心资源管理器报错,甚至崩溃【原】
    如何解决“应用程序并行配置不正确”问题?【原】
    STL,ATL,WTL的联系与区别
    C++虚函数表解析(转)
    学各国语言的网站大全
    The 500 Most Commonly Used Words in the English Language
    Top 100 English Verbs
    Top 100 words for advanced learners.
    TOP 100 MISSPELT/MISSPELLED WORDS IN ENGLISH
  • 原文地址:https://www.cnblogs.com/wzjhoutai/p/6953137.html
Copyright © 2020-2023  润新知