ZJU 3331 神奇的双塔DP

 

大致题意:
    有两个机器a,b。要处理n个部件,第i个部件在机器a上完成需要x[i],在b机器上需要y[i],每个部件只能选择一个机器来完成。且当地i个部件开始加工时前[1,i-1]部件必须已经完成或者正在被加工。求加工完所有n个部件的最小时间是多少。

 

大致思路:
    好神的dp,这里的状态表示非常奇怪。dp[i][j]代表的是,当加工到第i个部件,a机器比b机器的时间多出j+100时的最少时间是多少。

    转移的时候就分别考虑当前任务放在a上或放在b上的最少时间分别是多少即可。

 

 

 

 

#include<iostream>
#include<algorithm>
#include<string.h>
#include<string>
#include<stdio.h>
#define inf 2139062143
#define M 100
using namespace std;

int n,x[120],y[120];
int dp[210][250];

int main()
{
	int t;
	cin>>t;
	while(t--)
	{
		int i,j,k;
		scanf("%d",&n);
		for(i=1;i<=n;i++)
			scanf("%d%d",&x[i],&y[i]);
		memset(dp,0x7f,sizeof(dp));
		dp[0][100]=0;
		for(i=0;i<n;i++)
		{
			for(j=0;j<=200;j++)
			{
				if(dp[i][j]==inf)
					continue;
				if(j>=100)
				{

					dp[i+1][x[i+1]+M]=min(dp[i+1][x[i+1]+M],dp[i][j]+x[i+1]);
					dp[i+1][j-y[i+1]]=min(dp[i+1][j-y[i+1]],dp[i][j]+max(0,y[i+1]-(j-M)));
				}
				else 
				{
					dp[i+1][M-y[i+1]]=min(dp[i+1][M-y[i+1]],dp[i][j]+y[i+1]);
					dp[i+1][j+x[i+1]]=min(dp[i+1][j+x[i+1]],dp[i][j]+max(0,x[i+1]-(M-j)));
				}

			}
		}
		int ans=inf;
		for(i=0;i<=200;i++)
			ans=min(dp[n][i],ans);
		printf("%d\n",ans);
	}
	return 0;
}


 

你可能感兴趣的:(ZJU 3331 神奇的双塔DP)