P9011 [USACO23JAN] Air Cownditioning II B(dfs+差分)

题目描述

With the hottest recorded summer ever at Farmer John's farm, he needs a way to cool down his cows. Thus, he decides to invest in some air conditioners.

Farmer John's N cows (1≤N≤20) live in a barn that contains a sequence of stalls in a row, numbered 1⋯1001⋯100. Cow i occupies a range of these stalls, starting from stall si​ and ending with stall ti​. The ranges of stalls occupied by different cows are all disjoint from each-other. Cows have different cooling requirements. Cow i must be cooled by an amount ci​, meaning every stall occupied by cow i must have its temperature reduced by at least ci​ units.

The barn contains M air conditioners, labeled 1⋯M(1≤M≤10). The i-th air conditioner costs mi​ units of money to operate (1≤mi​≤1000) and cools the range of stalls starting from stall ai​ and ending with stall bi​. If running, the i-th air conditioner reduces the temperature of all the stalls in this range by pi​(1≤pi​≤106). Ranges of stalls covered by air conditioners may potentially overlap.

Running a farm is no easy business, so FJ has a tight budget. Please determine the minimum amount of money he needs to spend to keep all of his cows comfortable. It is guaranteed that if FJ uses all of his conditioners, then all cows will be comfortable.

输入格式

The first line of input contains N and M.

The next N lines describe cows. The ith of these lines contains si​,ti​, and ci​.

The next M lines describe air conditioners. The ith of these lines contains ai​,bi​,pi​, and mi​.

For every input other than the sample, you can assume that M=10.

输出格式

Output a single integer telling the minimum amount of money FJ needs to spend to operate enough air conditioners to satisfy all his cows (with the conditions listed above).

题意翻译

题目描述

农夫约翰的 N 头奶牛 (1≤N≤20) 住在一个谷仓里,谷仓里有连续的牛栏,编号为 1−1001−100 。 奶牛 i 占据了编号 [si​,ti​] 的牛栏。 不同奶牛占据的牛栏范围是互不相交的。 奶牛有不同的冷却要求,奶牛 i 占用的每个牛栏的温度必须至少降低 ci​ 单位。

谷仓包含 M 台空调,标记为 1−M (1≤M≤10)。第 i 台空调需要花费 mi​ 单位的金钱来运行 (1≤mi​≤1000) ,如果运行,第 i 台空调将牛栏 [ai​,bi​] 所有牛栏的温度降低 pi​(1≤pi​≤106)。 空调覆盖的牛栏范围可能会重叠。

请帮助农夫约翰求出满足所有奶牛需求要花费的最少金钱。

输入格式

第一行两个整数,分别为 N 和 M。

第 22 至 (N+1) 行,每行三个整数,分别为 si​、ti​ 和 ci​ 。

第 (N+2) 至 (M+N+1) 行,每行四个整数, 分别为 ai​、bi​、pi​ 和 mi​。

输出格式

一个整数,表示最少花费的金钱。

提示

样例解释 1

一种花费最少的可能解决方案是选择那些冷却区间为 [2,9][2,9] 、[1,2][1,2] 和 [6,9][6,9] 的空调,成本为 3+2+5=103+2+5=10 .

数据范围

对于 100%100% 的数据,1≤N≤20, 1≤M≤10, 1≤ai​,bi​,si​,ti​≤100, 1≤ci​,pi​≤106,1≤mi​≤1000。

输入输出样例

输入 

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

说明/提示

Explanation for Sample 1

One possible solution that results in the least amount of money spent is to select those that cool the intervals [2,9],[1,2][2,9],[1,2], and [6,9][6,9], for a cost of 3+2+5=103+2+5=10.

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int M=4e4+10;
const int N=1e2+10;
int n,m;
int x,y,z;
int a[N];
int minn=INT_MAX;
struct p{
	int u,v,t,w;
}b[11];
void dfs(int pos,int sum)
{
	if(pos==m+1)
	{
		for(int i=1;i<=100;i++)
		{
			if(a[i]<=0)
			continue;
			else
			return ;
		}
		minn=min(minn,sum);
		return ;
	}
	for(int i=b[pos].u;i<=b[pos].v;i++)
	a[i]-=b[pos].t;
	dfs(pos+1,sum+b[pos].w);
	for(int i=b[pos].u;i<=b[pos].v;i++)
	a[i]+=b[pos].t;
	dfs(pos+1,sum);
}
void solve()
{
	cin>>n>>m;
	for(int i=1;i<=n;i++)
	{
		cin>>x>>y>>z;
		a[x]+=z;a[y+1]-=z;//差分优化 
	}
	for(int i=1;i<=100;i++)
	a[i]+=a[i-1];
	for(int i=1;i<=m;i++)
	cin>>b[i].u>>b[i].v>>b[i].t>>b[i].w;
	dfs(1,0);
	cout<<minn<<endl;
}
int main()
{
	ios::sync_with_stdio(0);
	cin.tie(0);cout.tie(0);
	ll t=1;
//	cin>>t;
	while(t--)
	{	
		solve();
	}
	return 0;
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是P4087 [USACO17DEC]Milk Measurement的c++代码: ```c++ #include<bits/stdc++.h> using namespace std; int n,d,i,x,minn=1e9,maxn=-1e9,sum=7;//注意sum要初始化为7,因为一开始有三个人挤奶! map<int,int> mp; struct node{ int day,milk,id;//day表示某一天,milk表示这一天的产奶量,id表示这头牛的编号 }a[100010]; bool cmp(node x,node y){ return x.day<y.day; } int main(){ scanf("%d%d",&n,&d); for(i=1;i<=n;i++){ scanf("%d%d%d",&a[i].day,&a[i].id,&a[i].milk); minn=min(minn,a[i].id);//记录最小的牛的编号 maxn=max(maxn,a[i].id);//记录最大的牛的编号 } sort(a+1,a+n+1,cmp);//排序 for(i=1;i<=n;i++){ int p=a[i].id; mp[p]+=a[i].milk;//记录每头牛产奶总量 if(mp[p]-a[i].milk>=mp[minn]&&mp[p]>=mp[minn]){//如果这头牛的产奶总量减去这一天的产奶量后等于最小产奶量且这头牛的产奶总量大于等于最小产奶量 sum--; } if(mp[p]>=mp[maxn]&&mp[p]-a[i].milk<mp[maxn]){//如果这头牛的产奶总量大于等于最大产奶量且这头牛的产奶总量减去这一天的产奶量小于最大产奶量 sum++; } if(mp[p]-a[i].milk<mp[maxn]&&mp[p]>=mp[maxn]){//如果这头牛的产奶总量减去这一天的产奶量小于最大产奶量且这头牛的产奶总量大于等于最大产奶量 if(mp[maxn]-mp[p]+a[i].milk>0)sum++; } mp[p]-=a[i].milk;//减去这一天的产奶量 if(i==n||a[i].day!=a[i+1].day){//如果到了新的一天或者到了最后一天 if(mp[maxn]!=mp[a[i].id]&&mp[a[i].id]>=mp[maxn])sum++;//如果这头牛的产奶总量不等于最大产奶量且这头牛的产奶总量大于等于最大产奶量 if(mp[maxn]==mp[a[i].id]){//如果这头牛的产奶总量等于最大产奶量 if(a[i].id==maxn)sum+=0;//如果这头牛就是最大产奶量的牛,那么不需要增加计数器 else sum++;//否则需要增加计数器 } if(mp[minn]!=mp[a[i].id]&&mp[a[i].id]>=mp[minn])sum++;//如果这头牛的产奶总量不等于最小产奶量且这头牛的产奶总量大于等于最小产奶量 if(mp[minn]==mp[a[i].id]){ if(a[i].id==minn)sum+=0;//如果这头牛就是最小产奶量的牛,那么不需要增加计数器 else sum++;//否则需要增加计数器 } } } printf("%d\n",sum); return 0; } ``` 该题的解题思路是模拟,需要注意细节问题。我们可以首先将输入的数据按天数排序,然后模拟每一天挤奶的情况,并根据题目要求进行计数即可。具体细节请见代码注释。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值