AtCoder Beginner Contest 167 C Skill Up 满足C(n,1),C(n,2),C(n,3),......,C(n,n)的深搜dfs

AtCoder Beginner Contest 167   比赛人数11940  比赛开始后15分钟看到A题,之后每隔一分钟,看到一道题,在比赛开始后第21分钟看到所有题

AtCoder Beginner Contest 167  C   Skill Up   满足C(n,1),C(n,2),C(n,3),......,C(n,n)的深搜dfs

总目录详见https://blog.csdn.net/mrcrack/article/details/104454762

在线测评地址https://atcoder.jp/contests/abc167/tasks/abc167_c

收获,在比赛中,独立悟出了   满足C(n,1),C(n,2),C(n,3),......,C(n,n)的深搜dfs  写法。

以样例1为例

Input:
3 3 10
60 2 2 4
70 8 7 9
50 2 3 9
Output:
120

枚举所有情况
(1)60 2 2 4
(2)70 8 7 9
(3)50 2 3 9
可有如下组合
(1)
(2)
(3)
(1)(2)
(1)(3)
(2)(3)
(1)(2)(3)
枚举上述组合,找出花费和值最小的情况。

以下为花费和值最小的情况
(2)70 8      7      9
(3)50 2      3      9
  120 10>=10 10>=10 18>=10

AC代码如下

#include <cstdio>
#include <algorithm>
using namespace std;
int n,m,x;
int c[15],a[15][15],b[15],d[15],len,sum=100000000,cost;
void init(){//数据读取
	int i,j;
	scanf("%d%d%d",&n,&m,&x);
	for(i=1;i<=n;i++){
		scanf("%d",&c[i]);
		for(j=1;j<=m;j++)
			scanf("%d",&a[i][j]);
	}
}
void dfs(int step){
	int i,j,k;
	if(step==len+1){//深搜结束条件
		for(k=1;k<=m;k++)d[k]=0;//d[k]表示被选择的书店,在k列位置上的和
		for(j=1;j<=len;j++)
			for(k=1;k<=m;k++)
				d[k]+=a[b[j]][k];//计算被选择的书店,在k列位置上的和
		for(k=1;k<=m;k++)
			if(d[k]<x)return;//不满足条件
		cost=0;
		for(j=1;j<=len;j++)cost+=c[b[j]];//计算花费
		sum=min(sum,cost);//找最小值
		return ;
	}
	for(i=b[step-1]+1;i<=n;i++)//找组合情况,就让后查找的位置越来越大,请注意i=b[step-1]+1
		b[step]=i,dfs(step+1);
}
int main(){
	init();
	for(len=1;len<=n;len++)//len界定选择的书店的数量
		b[0]=0,dfs(1);
	if(sum==100000000)printf("-1\n");//没找到
	else printf("%d\n",sum);
	return 0;
}

类似的题目有:

AtCoder Beginner Contest 165 C Many Requirements 深搜dfs+生成非递减数组

AtCoder Beginner Contest 159 E Dividing Chocolate 二维前缀和+子矩阵和+深搜行+枚举列+注意行边界处理+注意列边界处理

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值