题目大意:lrj306页 习题9-8 想了很久,区间DP的状态意识到了,但是不知道这个怎么和deadline联系起来,最后看别人的解题报告,恍然大悟,原来如此,顺便练了一下滚动数组,还是很有收获的。
题目链接:https://vjudge.net/problem/UVA-1632
第一份代码没有使用滚动数组,第二份使用了滚动数组,第二份比第一份的速度要上不少。
#include <cstdio>
#include <iostream>
#include <cstring>
#define min(a,b) (((a)<(b))?(a):(b))
using namespace std;
const int maxn = 10005 , inf = 0x3f3f3f3f;
int a[maxn] , d[maxn];
int dp[maxn][maxn][2];
int n;
void solve () {
for (int i = 1 ; i <= n ; i++)
dp[i][i][0] = dp[i][i][1] = 0;
for (int i = n-1 ; i >= 1 ; i--) {
for (int j = i+1 ; j <= n ; j++) {
dp[i][j][0] = min(dp[i+1][j][0]+a[i+1]-a[i] , dp[i+1][j][1]+a[j]-a[i]);
if (dp[i][j][0] >= d[i]) dp[i][j][0] = inf;
dp[i][j][1] = min(dp[i][j-1][1]+a[j]-a[j-1] , dp[i][j-1][0]+a[j]-a[i]);
if (dp[i][j][1] >= d[j]) dp[i][j][1] = inf;
}
}
int ans = min(dp[1][n][0] , dp[1][n][1]);
if (ans >= inf)
cout << "No solution" << endl;
else
cout << ans << endl;
}
int main () {
while (cin >> n) {
memset (a,0,sizeof(a));
memset (d,0,sizeof(d));
memset (dp,0,sizeof(dp));
for (int i = 1 ; i <= n ; i++)
scanf("%d%d" , &a[i] , &d[i]);
solve();
}
}
#include <cstdio>
#include <iostream>
#include <cstring>
#define min(a,b) (((a)<(b))?(a):(b))
using namespace std;
const int maxn = 10005 , inf = 0x3f3f3f3f;
int a[maxn] , d[maxn];
int dp[2][maxn][2];
int n;
void solve () {
dp[(n&1)^1][n][1] = dp[(n&1)^1][n][0] = 0;
for (int i = n-1 ; i >= 1 ; i--) {
int x = (i&1)^1;
for (int j = i+1 ; j <= n ; j++) {
dp[x][j][0] = min(dp[x^1][j][0]+a[i+1]-a[i] , dp[x^1][j][1]+a[j]-a[i]);
if (dp[x][j][0] >= d[i]) dp[x][j][0] = inf;
dp[x][j][1] = min(dp[x][j-1][1]+a[j]-a[j-1] , dp[x][j-1][0]+a[j]-a[i]);
if (dp[x][j][1] >= d[j]) dp[x][j][1] = inf;
}
}
int ans = min(dp[0][n][0] , dp[0][n][1]);
if (ans >= inf)
cout << "No solution" << endl;
else
cout << ans << endl;
}
int main () {
while (cin >> n) {
memset (a,0,sizeof(a));
memset (d,0,sizeof(d));
memset (dp,0,sizeof(dp));
for (int i = 1 ; i <= n ; i++)
scanf("%d%d" , &a[i] , &d[i]);
solve();
}
}