动态规划的思想。同时需要注意一点,不论我们从哪一个点开始进行操作,任意时候为了得到最优的结果,那么我们操作的肯定是一个连续的区间。所以在这道题目当中我们就可以使用滚动数组来进行操作,并且能够优化内存。代码中
dp[i][j][k]其中i用来区分是当前待更新的数组还是上一次记录的状态数组,j代表着当前区间的左端点,k代表着当前的位置是在区间的左边还是右边,具体实现见如下代码:
#include<iostream>
#include<vector>
#include<string>
#include<set>
#include<stack>
#include<queue>
#include<map>
#include<algorithm>
#include<cmath>
#include<iomanip>
#include<cstring>
#include<sstream>
#include<cstdio>
#include<deque>
using namespace std;
class Solve{
public:
int N;
int location[10010], deadline[10010];
int dp[2][10010][2];//滚动数组,0代表左边,1代表右边
int Inf = 1 << 20;
void deal(){
int cur = 0;
for (int i = 0; i < N; i++){
dp[cur][i][0] = dp[cur][i][1] = (deadline[i]>0?0:Inf);
}
for (int i = 1; i < N; i++){
cur = cur ^ 1;
for (int j = 0; j < N - i; j++){
dp[cur][j][0] = min(dp[cur^1][j + 1][0] + location[j + 1] - location[j],
dp[cur^1][j+1][1]+location[j+i]-location[j]);
dp[cur][j][1] = min(dp[cur ^ 1][j][1] + location[j + i] - location[j + i - 1],
dp[cur^1][j][0]+location[j+i]-location[j]);
if (dp[cur][j][0]>=deadline[j]) dp[cur][j][0] = Inf;
if (dp[cur][j][1]>=deadline[j + i]) dp[cur][j][1] = Inf;
}
}
int ans = min(dp[cur][0][0], dp[cur][0][1]);
if (ans == Inf) cout << "No solution\n";
else cout << ans << endl;
}
};
int main(){
Solve a;
while (cin >> a.N){
for (int i = 0; i < a.N; i++)
cin >> a.location[i] >> a.deadline[i];
a.deal();
}
return 0;
}