题目链接:
http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3331
题解:
双塔dp。
代码:
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
#define met(a,b) memset(a,b,sizeof(a))
#define inf 0x3f3f3f3f
const int maxn = 100+10;
int a[maxn],b[maxn];
int dp[maxn][2*maxn];
//dp[i][j]表示第i个任务的时候,a塔b塔的高度差。
int main()
{
int t;
cin>>t;
while(t--)
{
int n;
cin>>n;
for(int i=1;i<=n;i++)
cin>>a[i]>>b[i];
int offset=100;
// 通过贪心的思想可以知道,如果满足最下的话,任务的时间差是不会超过100的。
for(int i=0;i<=n;i++)
for(int j=0;j<=200;j++)
dp[i][j]=inf;
dp[0][0+offset]=0;
// dp的初始化。
for(int i=1;i<=n;i++)
{
for(int j=-99;j<=99;j++)
{
if(dp[i-1][j+offset]==inf)
continue;
if(j<0)
// b塔比较高的话
{
dp[i][-b[i]+offset]=min(dp[i][-b[i]+offset],dp[i-1][j+offset]+b[i]);
// b塔放任务
dp[i][j+offset+a[i]]=min(dp[i][j+offset+a[i]],dp[i-1][j+offset]+max(0,a[i]+j));
// a塔放任务
}
else
// a塔比较高
{
dp[i][offset+a[i]]=min(dp[i][offset+a[i]],dp[i-1][j+offset]+a[i]);
dp[i][j+offset-b[i]]=min(dp[i][j+offset-b[i]],dp[i-1][j+offset]+max(0,b[i]-j));
}
}
}
int MIN=inf;
for(int i=-99;i<=99;i++)
MIN=min(MIN,dp[n][i+offset]);
cout<<MIN<<endl;
}
}
有待更新