SRM 604 D2L3:FoxConnection2,dp

题目:http://community.topcoder.com/stat?c=problem_statement&pm=12951&rd=15837

参考:http://apps.topcoder.com/wiki/display/tc/SRM+604

dp状态不好想,而且用dfs来构造树也不好想,很难的题目。

代码:

#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 MOD = 1e9 + 7;
const int MAX = 55;
long long dp[MAX][MAX][MAX];	// dp[x][e][k] 表示以x为根的树,若不考虑其前e个孩子,能选出顶点数为k的且以x为根的子树的种数
int g[MAX][MAX];		// g[x][e] 表示顶点x的第e个孩子
int degree[MAX];		// degree[x] 表示顶点x的孩子数

class FoxConnection2 {
public:
	// 使用dfs构造树, 求出各顶点的孩子
	void dfsMakeTree(int x, int parent, vector <int> & A, vector <int> & B)
	{
		degree[x] = 0;
		for (int i = 0; i < A.size(); i++) {
			if (x == A[i] - 1 && parent != B[i] - 1) {	// B[i] - 1 是 x的孩子
				g[x][ degree[x] ] = B[i] - 1;		// 顶点从0开始编号
				++degree[x];
				dfsMakeTree( B[i] - 1, x, A, B );	// 构造孩子树
			}
			if (x == B[i] - 1 && parent != A[i] - 1) {
				g[x][ degree[x] ] = A[i] - 1;
				++degree[x];
				dfsMakeTree( A[i] - 1, x, A, B);
			}
		}
	}
	
	int rootedWays(int x, int e, int k)
	{
		long long & res = dp[x][e][k];
		if (e == degree[x]) {
			return (k == 1 ? 1 : 0);
		}
		if (res != -1) {
			return res;
		}
		
		res = rootedWays(x, e + 1, k);	// 第一颗子树不提供,全部由剩下的树提供
		for (int i = 1; i < k; i++) {	// 第一颗子树提供i个,剩下的树提供k-i个
			res += rootedWays(g[x][e], 0, i) * rootedWays(x, e + 1, k - i);
			res %= MOD;
		}
		return res;
	}

	int ways(vector <int> A, vector <int> B, int k) {
		long long res = 0;
		memset(dp, -1, sizeof(dp));
		memset(degree, 0, sizeof(degree));
		memset(g, 0, sizeof(g));
		dfsMakeTree(0, -1, A, B);
		for (int i = 0; i < A.size() + 1; i++) {
			res += rootedWays(i, 0, k);
			res %= MOD;
		}
		return res;
	}

};

/************** Program End ************************/


weixin073智慧旅游平台开发微信小程序+ssm后端毕业源码案例设计 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。
python017基于Python贫困生资助管理系统带vue前后端分离毕业源码案例设计 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值