SRM 591 D2L3:YetAnotherTwoTeamsProblem,dp

题目: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 ************************/



  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值