【题解】AOJ 0525 Osenbei(搜索)

AOJ 0525 Osenbei


题意

https://vjudge.net/problem/Auzi-0525

IOI制果公司用创业以来的传统制法煎制煎饼。这种传统制法是用炭火在一定时间内烤正面,正面烤后翻转,用炭火在一定时间内烤背面。保持着这个传统,用机器煎煎饼。该机器将煎饼排成纵R(1≤R≤10)行、横C(1≤C≤10000)列的长方形来烤。通常是自动驾驶,正面烤好后一齐把煎饼翻过来背面烤。有一天,煎煎饼的时候,在翻煎饼之前发生了地震,几张煎饼都翻了。幸运的是,炭火的状态还保持在适当的状态,但如果再烧到正面,就会超过创业以来的传统规定的烧时间,煎饼的正面会被烧得太久,无法作为商品上市。于是,他赶紧把机器改为手动操作,只把还没有翻过来的煎饼翻过来。这台机器,可以同时翻过来几行横的,同时翻过来几列竖的,可惜的是,煎饼一张一张地翻不过来。取的,需要时间和地震中没有里返ら煎饼的间前面太烧作为商品无法发货,所以旁边的几行,同时一次翻过来,继续,纵向的几排翻过来,同时一次间前面不太烤两面可以烤煎饼,也就是说,“可以出货煎饼”决定尽可能多的数量。也考虑横的行一行也不翻转,或者纵的列一列也不翻转的情况。请写下输出能出货的煎饼张数最大值的程序。地震之后,煎饼就变成了下面这个样子。黑色圆圈表示正面烧制的状态,白色圆圈表示背面烧制的状态。(用的翻译软件,大概意思理解就好)
注意,R的上限10小于C的上限10000。
输入由多个数据集组成。每个数据集以以下形式给出:在输入的第一行中,以空白为间隔写有两个整数R、C(1≤R≤10,1≤C≤10 000)。接着的R行表示地震后的煎饼状态。第(i+1)行(1≤i≤R)有C个整数ai,1, ai,2,……, ai,C以空白为间隔写,ai,j表示i行j列的煎饼状态。ai,j为1表示正面烧制,0表示背面烧制。当C和R均为0时,指示输入结束,数据集的数目不超过5。
每个输出数据集输出1行可发货的煎饼的最大张数。


题解

思路:因为行数最多只有10行,所以先确定行再判断列,行的话最多是210种可能,然后每种可能再去判断列,使得列中的1数量最多。具体细节看代码注释。

#include<iostream>

using namespace std;

int r, c;
int arr[15][10005];
int ans;

void dfs(int t) {//t是行号
	
	if(t == r) {	//最后一行
		int sum = 0;	//记录整个行列中1的数量
		for(int i = 0; i < c; i++) {
			int tsum = 0;//记录当前列中1的数量
			for(int j = 0; j < r; j++)
				tsum += arr[j][i];	//因为是1,0两种状态,所以直接相加即可
			sum += max(tsum, r - tsum);//如果1多就直接加,不然就反转
		}
		ans = max(ans, sum);//ans是最终值,如果sum比ans大就替代
		return;
	}
	dfs(t + 1);//第t行不反转,进入下一行
	for(int i = 0; i < c; i++)//反转当前行
		arr[t][i] = !arr[t][i];
	dfs(t + 1);//反转后进入的下一行
}
int main() {
	
	while(cin >> r >> c, r + c) {
		
		for(int i = 0; i < r; i++)
			for(int j = 0; j < c; j++)
				cin >> arr[i][j];
		
		ans = 0;
		dfs(0);
		cout << ans << endl;
	} 
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值