1. 程式人生 > >[UVALive 6661 Equal Sum Sets] (dfs 或 dp)

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

dsm ems live pos algorithm n) uva for %d

題意:

求從不超過 N 的正整數其中選取 K 個不同的數字,組成和為 S 的方法數。

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


解題思路:

  DFS:

  因為N,K。S的範圍非常小。直接DFS就可以。

/*
ID: [email protected]
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\n", 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: [email protected]
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\n", dp[n][s][k]);
}


  

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