UVALive 3971 Assemble 电脑配件 二分+贪心

本文探讨如何在预设预算内,通过贪心算法和二分查找技巧,找到组装电脑配件中质量最经济的选择。重点在于合理排序与算法应用,避免超支的同时追求性价比最高的配置方案。

题意:某人想组装电脑,有很多电脑配件可以选,每样都有它的价格和质量,每种配件一定要买一个,现在给出钱数,求能组装出来的电脑里面配件质量最便宜的是多少。当然不能超出预算的啦。

每次枚举那个最便宜的,然后贪心,每次找价格最小且价格大于最便宜的,如果超支就向前二分,否则向后二分。

这题折腾了一晚上 = =,差点跪了。。。最后发现排序没处理好,郁闷。。。得先排前再排质量。

代码:

/*
*  Author:      illuz <iilluzen[at]gmail.com>
*  Blog:        http://blog.youkuaiyun.com/hcbbt
*  File:        l3971.cpp
*  Create Date: 2013-09-09 21:14:09
*  Descripton:  binary, greedy 
*/

#include <cstdio>
#include <vector>
#include <iostream>
#include <map>
#include <set>
#include <algorithm>
using namespace std;

const int MAXN = 1000;

struct P {
	string nam;
	int mon;
	int qua;
	friend bool operator < (const P &a, const P &b) {
		if (a.mon != b.mon)
			return a.mon < b.mon;
		return a.qua > b.qua; 
	}
	P() {}
	P(string s, int m, int q) {
		nam = s;
		mon = m;
		qua = q;
	}
};
int n, b, cnt;
set<P> v[MAXN];
map<string, int> app;

bool judge(int m) {
	int sum = 0;
	for (int i = 1; i < cnt; i++) {
		bool choose = false;
		for (set<P>::iterator j = v[i].begin(); j != v[i].end(); j++) {
			if ((*j).qua >= m) {
				//				cout << sum << ' ';
				choose = true;
				sum += (*j).mon;
				break;
			}
		}
		if (false == choose || sum > b)
			return false;
	}
	return true;
}

int main() {
	int t;
	string tmp;
	scanf("%d", &t);
	while (t--) {
		scanf("%d%d", &n, &b);
		int tm, tq;
		int L = 0, R = 0, mid;
		app.clear();
		for (int i = 1; i < cnt; i++)
			v[i].clear();
		cnt = 1;
		for (int i = 0; i < n; i++) {
			cin >> tmp;
			scanf("%*s%d%d", &tm, &tq);
			R = max(R, tq);
			if (app[tmp] == 0) {
				app[tmp] = cnt;
				v[cnt++].insert(P(tmp, tm, tq));
			}
			else
				v[app[tmp]].insert(P(tmp, tm, tq));
		}
		while (L < R) {
			mid = L + (R - L) / 2;
			if (L == mid) break;
			if (judge(mid)) L = mid;
			else R = mid;
			//	cout << "\n!!!!!!!!!!!!" << mid << endl;
		}
		if (judge(mid + 1)) mid++;
		printf("%d\n", mid);
	}
	return 0;
}


<think>我们正在讨论的是如何在Gradle中配置自动分类打包(assemble)。根据用户之前的上下文,用户已经了解了`minifyEnabled`的作用和配置,现在希望进一步了解如何通过Gradle命令来自动化打包,特别是如何根据不同的分类(比如不同的productFlavor和buildType)进行打包。 从引用[1]中我们可以知道,Gradle提供了`assemble`命令来编译所有productFlavor和buildType的APK,同时也可以指定特定的productFlavor和buildType来编译特定的APK。例如: - `gradle assemble`:编译所有变体 - `gradle assembleFlavorRelease`:编译特定flavor的release版本 用户希望的是“自动分类打包”,也就是能够按照一定的分类(比如不同的渠道、不同的构建类型)自动执行打包任务。我们可以通过配置Gradle的构建变体(build variants)来实现,构建变体由productFlavor和buildType组合而成。 ### 配置步骤 #### 1. 定义productFlavors(渠道) 在`build.gradle`文件中,我们可以定义多个productFlavor,每个代表一个渠道或一个分类。例如: ```groovy android { flavorDimensions "version" productFlavors { free { dimension "version" // 这里可以配置free版本特有的设置 } paid { dimension "version" // 这里可以配置paid版本特有的设置 } } } ``` #### 2. 定义buildTypes(构建类型) 通常,Android项目默认有debug和release两种构建类型。我们也可以自定义其他类型,例如: ```groovy android { buildTypes { release { minifyEnabled true proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' } debug { minifyEnabled false } staging { // 可以复制release的配置,然后修改部分 initWith release // 例如,修改applicationId后缀 applicationIdSuffix ".staging" } } } ``` #### 3. 组合构建变体 配置了productFlavors和buildTypes后,Gradle会自动生成对应的构建变体(variants)。例如,上面的配置会生成以下变体: - freeDebug - freeRelease - freeStaging - paidDebug - paidRelease - paidStaging #### 4. 执行分类打包 我们可以通过以下命令来打包特定的变体: - 打包所有变体:`gradle assemble`(或`./gradlew assemble`) - 打包所有free变体:`gradle assembleFree`(这会生成freeDebug, freeRelease, freeStaging) - 打包所有release变体:`gradle assembleRelease`(这会生成freeRelease, paidRelease) - 打包特定的变体:`gradle assembleFreeRelease` #### 5. 自动化打包脚本 我们可以编写一个脚本(如shell脚本或bat脚本)来执行一系列Gradle命令,实现自动分类打包。例如,一个简单的shell脚本(macOS/Linux): ```bash #!/bin/bash # 打包所有free版本 ./gradlew assembleFree # 打包所有paid的release版本 ./gradlew assemblePaidRelease ``` 对于Windows,可以编写一个bat脚本: ```bat @echo off gradlew assembleFree gradlew assemblePaidRelease ``` #### 6. 进阶:使用Gradle任务依赖 我们也可以自定义Gradle任务,将多个打包任务组合起来。例如,在`build.gradle`中定义一个任务,让它依赖于多个assemble任务: ```groovy task assembleAllFree(type: GradleBuild) { tasks = ['assembleFreeDebug', 'assembleFreeRelease', 'assembleFreeStaging'] } task assembleAllPaid(type: GradleBuild) { tasks = ['assemblePaidDebug', 'assemblePaidRelease', 'assemblePaidStaging'] } task assembleAllRelease(type: GradleBuild) { tasks = ['assembleFreeRelease', 'assemblePaidRelease'] } ``` 然后就可以通过`gradle assembleAllFree`等命令来执行分类打包。 ### 注意事项 - 在命令行中执行Gradle命令时,使用`gradlew`(Gradle Wrapper)而不是全局的`gradle`命令,这样可以保证使用项目指定的Gradle版本。 - 如果项目是多模块的,可以在命令中指定模块,例如:`gradlew :app:assembleFreeRelease`。 ### 引用说明 根据引用[1],我们了解到Gradle的assemble命令可以指定productFlavor和buildType,并且支持缩写。引用[2]和[3]则提供了关于自动化打包的配置和环境设置的背景。引用[4]提到了敏感信息的处理,虽然与当前问题不直接相关,但在实际打包中,如果涉及签名和加固,可以参考其方法。 ### 总结 通过配置productFlavors和buildTypes,我们可以定义多个构建变体,然后使用Gradle的assemble命令按分类打包。同时,我们可以通过脚本或自定义Gradle任务来进一步自动化这个过程。 §§相关问题§§ 1. 如何在Gradle中配置多渠道打包(如友盟统计)? 2. 如何自定义Gradle任务以实现更复杂的打包流程? 3. 在自动化打包中,如何自动增加版本号并生成对应APK文件名? 4. 如何通过Gradle命令只打包特定模块?</think>在 Gradle 中配置自动分类打包(assemble)主要通过 **productFlavors** 和 **buildTypes** 的组合实现,以下是详细配置步骤和示例: ### 一、核心配置方法(build.gradle) ```groovy android { // 1. 定义构建类型 buildTypes { release { minifyEnabled true proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } debug { applicationIdSuffix ".debug" // 添加调试后缀 } staging { // 自定义构建类型 initWith release // 继承release配置 applicationIdSuffix ".staging" } } // 2. 定义产品风味(分类维度) flavorDimensions "channel", "version" productFlavors { // 渠道维度 free { dimension "channel" applicationIdSuffix ".free" } paid { dimension "channel" applicationIdSuffix ".paid" } // 版本维度 basic { dimension "version" versionNameSuffix "-basic" } pro { dimension "version" versionNameSuffix "-pro" } } } ``` ### 二、打包命令分类执行 配置后会自动生成组合任务,按分类执行打包: ```bash # 1. 打包所有变体 ./gradlew assemble # 2. 按构建类型打包 ./gradlew assembleRelease # 所有release版本 ./gradlew assembleDebug # 所有debug版本 ./gradlew assembleStaging # 所有staging版本 # 3. 按渠道打包 ./gradlew assembleFree # 所有free渠道变体 ./gradlew assemblePaid # 所有paid渠道变体 # 4. 按版本打包 ./gradlew assembleBasic # 所有基础版 ./gradlew assemblePro # 所有专业版 # 5. 精确组合打包 ./gradlew assembleFreeProRelease # free渠道+pro版+release类型 ./gradlew assemblePaidBasicDebug # paid渠道+basic版+debug类型 ``` ### 三、自动化打包增强技巧 1. **自动输出路径配置** 在`build.gradle`中添加APK重定向: ```groovy android.applicationVariants.all { variant -> variant.outputs.all { output -> def formattedDate = new Date().format('yyyyMMdd') outputFileName = "${variant.flavorName}_${variant.buildType.name}_v${variant.versionName}_${formattedDate}.apk" } } ``` 2. **敏感信息安全处理**(引用[4]) 创建`secrets.properties`文件: ```properties KEY_PATH=/path/to/keystore KEY_PASSWORD=your_password ``` 在`build.gradle`中读取: ```groovy def secrets = new Properties() file("secrets.properties").withInputStream { secrets.load(it) } signingConfigs { release { storeFile file(secrets.getProperty("KEY_PATH")) storePassword secrets.getProperty("KEY_PASSWORD") } } ``` ### 四、典型目录结构 ``` app/ ├── build/ │ └── outputs/ │ └── apk/ │ ├── free/ # 免费渠道 │ │ ├── debug/ │ │ └── release/ │ └── paid/ # 付费渠道 │ ├── debug/ │ └── release/ └── src/ ├── free/ # 免费渠道专属代码 ├── paid/ # 付费渠道专属代码 └── main/ # 公共代码 ``` ### 五、执行效果示例 ```bash $ ./gradlew assembleFreeRelease > 生成APK: app-free-release-v1.0_20230815.apk $ ./gradlew assemblePaidBasicDebug > 生成APK: paid-basic-debug-v1.0_20230815.apk ``` > **最佳实践**:结合持续集成(CI)工具(如Jenkins),可通过`./gradlew assembleFreeRelease assemblePaidRelease`实现每日自动构建[^2]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值