2014编程之美资格赛 题目3 : 格格取数

时间限制: 2000ms
单点时限: 1000ms
内存限制: 256MB

描述

给你一个m x n (1 <= m, n <= 100)的矩阵A (0<=aij<=10000),要求在矩阵中选择一些数,要求每一行,每一列都至少选到了一个数,使得选出的数的和尽量的小。


输入

多组测试数据。首先是数据组数T

对于每组测试数据,第1行是两个正整数m, n,分别表示矩阵的行数和列数。

接下来的m行,每行n个整数,之间用一个空格分隔,表示矩阵A的元素。


输出

每组数据输出一行,表示选出的数的和的最小值。


数据范围

小数据:1 <= m, n <= 5

大数据:1 <= m, n <= 100

样例输入
2
3 3
1 2 3
3 1 2
2 3 1
5 5
1 2 3 4 5
5 1 2 3 4
4 5 1 2 3
3 4 5 1 2
2 3 4 5 1
样例输出
Case 1: 3
Case 2: 5
大数据没有什么思路。小数据直接深搜暴力解决了。108ms
//source here
#include<stdio.h>
#include<string.h>
int r[6],c[6];
int n,m,res;
int mp[6][6];
void dfs(int min) {
	int i,j,flg=0;
	if(min>=res) return ;
	for(i=0;i<n;i++){
		if(!r[i]){
			flg=1;break;	
			}
	for(i=0;i<m;i++){
		if(!c[i]) {
			flg=1;break;
		}
	}
	if(!flg) {
		if(min<res)
			res=min;
		return ;
	}	
	for(i=0;i<n;i++) {
		for(j=0;j<m;j++) {
			int x=1,y=1;
			if(!r[i]||!c[j]) {
				if(!r[i]) x=0;
				if(!c[j]) y=0;
				r[i]=1,c[j]=1;
				dfs(min+mp[i][j]);	
				if(!x) r[i]=0;
				if(!y) c[j]=0; 							
			}	
			}
	return ;
}
void init() {
	memset(r,0,sizeof(r));
	memset(c,0,sizeof(c));
}
int main() {
	int t,o=1;
	scanf("%d",&t);
	while(t--) {
		init();
		scanf("%d%d",&n,&m);
		int i,j,k;
		for(i=0;i<n;i++){
			for(j=0;j<m;j++) {
				scanf("%d",&mp[i][j]);
			}
		}
		res=999999;
		dfs(0);
		printf("Case %d: %d\n",o++,res);
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值