一、
题目描述
Farmer John 的农场记录到夏天以来最热的气温,他需要一些方法来给他的奶牛降温。因此,他决定去投资购买一些空调。
Farmer John的N头牛(1≤N≤20)住在一个谷仓里,谷仓里包含了一排牛棚,每个牛棚对应编号为1…100。第i头牛占用了一个范围内的所有牛棚,范围从si到ti。不同奶牛之间占用的牛棚相互分开,不会重合。不同的奶牛有不同的降温要求,第i头牛要求降低至少ci,这意味着它占用的所有牛棚都必须降低至少ci度。
谷仓里有M台空调,编号从1…M (1≤M≤10). 开第i台空调需要的花费是mi(1≤mi≤1000),同时,这台空调能减低第ai到第bi个牛棚的温度。空调开启之后,它能减低它范围内所有牛棚pi度(1≤pi≤10^6)。不同空调控制的范围可能会重合。
运营一个农场不是个容易的事情,FJ的预算紧张。请帮FJ找到最少的费用,来确保每头奶牛的需求都能被满足。数据确保如果开了所有的空调,每头奶牛都能有满意的温度。
输入
第一行包含两个整数N和M。
接下来N行描述每头奶牛的情况,包含si,ti和ci。
接下来M行描述每台空调的情况,第i行包含ai,bi,pi和mi。
除了样例以外的其他所有输入,能确保M = 10.
输出
输出一个整数,表示最低的能让所有奶牛都满意的费用。
样例
输入
复制
2 4
1 5 2
7 9 3
2 9 2 3
1 6 2 8
1 2 4 2
6 9 1 5
输出
复制
10
说明
对应样例输入,一个最低费用的解决方案是选择范围为 [2,9], [1,2]和 [6,9]这三台空调,花费的费用为 3+2+5=10.
二、分析
M=10,方案数为2的M次方,最多1024个方案,dfs枚举创建方案。
每个空调的状态从 0 0 0 0 0 0 0 0 0 0 ~ 1 1 1 1 1 1 1 1 1 1。
每个牛棚位置需要降低温度存储在a数组,不同的空调状态每个牛棚位置降低点温度存储在b数组,比较是否满足牛棚降低温度的需要,寻找较小花费值。
三、代码
#include <bits/stdc++.h>
using namespace std;
const int N=110;
int n,m,ans=1e6;
int a[N],b[N],st[N],ed[N],val[N],cost[N];
//a:每个围栏需要降低的温度,b:开启空调围栏降低了的温度
int check(string subset) {
int cur=0;
memset(b,0,sizeof(b));
for(int i=0;i<subset.size();i++){
if(subset[i]=='1'){
for(int j=st[i];j<=ed[i];j++){
b[j]+=val[i];
}
cur+=cost[i];
}
}
bool ok=true;
for(int i=1;i<=100;i++){
if(a[i]>b[i]){
ok=false;
break;
}
}
if(ok) return cur;
else return 1e6;
}
void build_subset(string curr) {
if (curr.size() == m) {
// 每一位代表一个空调的状态,所有空调的状态就位
ans = min(ans, check(curr));
// int t=check(curr);
// cout<<ans<<' ' <<t<<endl;
// if(ans>t)ans=t;
} else {
build_subset(curr + "1"); // 用
build_subset(curr + "0"); // 不用
}
}
int main() {
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++){
int x,y,z;scanf("%d%d%d",&x,&y,&z);
for(int j=x;j<=y;j++) a[j]=z;
}
for(int i=0;i<m;i++){ //字符串从0开始,所以空调也是从0开始
scanf("%d%d%d%d",&st[i],&ed[i],&val[i],&cost[i]);
//ans+=cost[i]; //所有空调全部开启必是一解
}
build_subset("");
printf("%d",ans);
return 0;
}