码迷,mamicode.com
首页 > 其他好文 > 详细

hdu5045(dp + 状态压缩)

时间:2015-03-17 21:57:05      阅读:151      评论:0      收藏:0      [点我收藏+]

标签:uva

题意:

给出n个人,m道题;每道题只能一个人做;现在给出n行m列.是每个人做每一道题的成功率;

你现在要选出哪些人做哪些题,使成功率和最大.但是有一个条件做到任意一题时,做最多的人只能比做最少的人多做一道;

就是如果10个人,那么前10题必须一人一题;


思路:

因为限制条件,所以前n道题,必须分给n个人一人一道,那么每人只能做一次;

那么用状态压缩表示哪些人做过了;

比如5个人00110;那么下一道题就可以选择剩下的3个人做,并且比较出一个最优的选择;

当状态变成11111时,就要重新置零;

所以用一个dp[i][j]表示前i道题,已经做的人的状态是j;


AC:


#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;

double p[15][1005];
double dp[1005][1 << 10];
int n,m;
double solve() {
	for(int i = 0; i <= m; i++) {
		for(int j = 0 ; j < (1 << n); j++) {
			dp[i][j] = -1.0;
		}
	}
	dp[0][0] = 0;
	for(int i = 0; i < m; i++) {
		for(int k = 0; k < (1 << n); k++) {
			if(dp[i][k] < 0)
				continue;
			int s;
			for(int j = 0; j < n; j++) {
				int tmp = 1 << j;
				if(k & tmp) continue;
				s = k | tmp;
				if(s == (1 << n) - 1)
					s = 0;
				dp[i + 1][s] = max(dp[i + 1][s], dp[i][k] + p[j][i]);
			}
		}
	}
	double ans = 0.0;
	for(int i = 0; i < (1 << n); i++) {
		ans = max(ans, dp[m][i]);
	}
	return ans;
}
int main() {
	int t;
	int cas = 1;
	scanf("%d",&t);
	while(t--) {
		scanf("%d%d",&n,&m);
		for(int i = 0; i < n; i++) {
			for(int j = 0; j < m; j++) {
				scanf("%lf",&p[i][j]);
			}
		}
		printf("Case #%d: %.5lf\n",cas++, solve());
	}
}


hdu5045(dp + 状态压缩)

标签:uva

原文地址:http://blog.csdn.net/yeyeyeguoguo/article/details/44349013

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!