题目:http://community.topcoder.com/stat?c=problem_statement&pm=12750&rd=15703
参考:http://apps.topcoder.com/wiki/display/tc/SRM+591
需要仔细分析2个条件,得出约束条件,再必须用迭代dp来实现,否则会超内存限制。
代码:
#include <algorithm>
#include <functional>
#include <numeric>
#include <utility>
#include <iostream>
#include <sstream>
#include <iomanip>
#include <bitset>
#include <string>
#include <vector>
#include <stack>
#include <deque>
#include <queue>
#include <set>
#include <map>
#include <cstdio>
#include <cstdlib>
#include <cctype>
#include <cmath>
#include <cstring>
#include <ctime>
#include <climits>
using namespace std;
#define CHECKTIME() printf("%.2lf\n", (double)clock() / CLOCKS_PER_SEC)
typedef pair<int, int> pii;
typedef long long llong;
typedef pair<llong, llong> pll;
#define mkp make_pair
/*************** Program Begin **********************/
const int MAX = 50 * 60000 / 2 + 60000;
long long dp[MAX];
class YetAnotherTwoTeamsProblem {
public:
int n, sum;
vector <int> skill;
//long long rec(int cur, int first)
//{
// 递归法,使用内存过大,不可用,dp[51][50 * 60000 / 2 + 60000]
// if (cur == n) {
// if (2 * first > sum) {
// return 1;
// } else {
// return 0;
// }
// }
// long long & res = dp[cur][first];
// if (res != -1) {
// return res;
// }
// res = 0;
// // not add skill[cur]
// res += rec(cur + 1, first);
// if (2 * first < sum) {
// // add skill[cur]
// res += rec(cur + 1, first + skill[cur]);
// }
// return res;
//}
long long count(vector <int> skill) {
long long res = 0;
n = skill.size();
sum = accumulate(skill.begin(), skill.end(), 0);
sort(skill.begin(), skill.end(), greater <int>());
this->skill = skill;
memset(dp, 0, sizeof(dp));
for (int cur = n; cur >= 0; cur--) {
for (int s = 0; s < MAX; s++) {
if (n == cur) {
dp[s] = (2 * s > sum ? 1 : 0);
continue;
}
if (2 * s < sum) {
dp[s] += dp[ s + skill[cur] ];
}
}
}
res = dp[0];
return res;
}
};
/************** Program End ************************/