任务分配(dp)

任务分配(dp)

Description

现有n个任务,要交给A和B完成。每个任务给A或给B完成,所需的时间分别为ai和bi。问他们完成所有的任务至少要多少时间。

Input

第一行一个正整数nn,表示有n个任务。
接下来有n行,每行两个正整数ai,bi。

Output

一个数,他们完成所有的任务至少要的时间。

Samples

Input

3
5 10
6 11
7 12

Output

12

Hint

【输入输出样例解释】
A完成任务1和任务2,时间为11。B完成任务3,时间为12。
或者 A完成任务1和任务3,时间为12。B完成任务2,时间为11。
【限制】
30%的数据满足:1≤n≤20
100%的数据满足:1≤n≤200, 1≤ai,bi≤200

思路:

三维dp比较好推,但是时间空间不允许。

正解是一种比较奇怪的dp状态。

dp[i] [j]的含义为完成前i个任务,A花费的时间为j;

dp[i] [j]的值表示完成前i个任务,B花费的时间。

划分依据为第i个任务由A还是B完成。

代码:

const int maxn=210;
int dp[maxn][maxn*maxn];
int a[maxn],b[maxn],n;
void solve(){
	n=read();
	for(int i=1;i<=n;i++){
		a[i]=read(),b[i]=read();
	}
	memset(dp,0x3f,sizeof dp);
	dp[0][0]=0;
	int sum=0;
	for(int i=1;i<=n;i++){
		sum=sum+a[i];
		for(int j=0;j<=sum;j++){
			dp[i][j]=dp[i-1][j]+b[i];//b完成第i个任务 
			if(j>=a[i]) dp[i][j]=min(dp[i][j],dp[i-1][j-a[i]]);//a完成第i个任务 
		}
	}
	int res=0x3f3f3f3f;
	for(int i=0;i<=sum;i++)///可能需要的时间 
		res=min(res,max(i,dp[n][i]));///注意取的先后顺序 
	cout<<res<<endl;
}

参考

posted @ 2021-02-03 12:16  OvO1  阅读(210)  评论(0编辑  收藏  举报