题意:直线上有n(n <= 10000)个点,其中第i个点的坐标是xi,且它会在di秒之后消失。alibaba可以从任意位置出发,求访问完所有点的最短时间.
分析:因为没有内存限制所以可以直接上n^2dp,但是我用了贪心的做法,优先访问di小的点,好像也没有什么不对(按di排序后每次选最小的去走).
更正做法,n^2 dp.
#include <bits/stdc++.h> using namespace std; typedef long long ll; const int N = 10005; int n,d[N],p[N]; int dp[N][N][2]; int main() { while(~scanf("%d",&n)) { for(int i = 1;i <= n;i++) { scanf("%d%d",&p[i],&d[i]); dp[i][i][0] = dp[i][i][1] = 0; } for(int l = 2;l <= n;l++) for(int i = 1;i + l - 1 <= n;i++) { int j = i + l - 1; memset(dp[i][j],0x3f,sizeof(dp[i][j])); ll temp = abs(p[i] - p[i+1]) + dp[i+1][j][0]; if(temp < d[i]) dp[i][j][0] = temp; temp = abs(p[j] - p[j-1]) + dp[i][j-1][1]; if(temp < d[j]) dp[i][j][1] = temp; dp[i][j][0] = min(dp[i][j][1] + abs(p[i] - p[j]),dp[i][j][0]); dp[i][j][1] = min(dp[i][j][0] + abs(p[i] - p[j]),dp[i][j][1]); } ll ans = min(dp[1][n][0],dp[1][n][1]); if(ans < 1000000000) cout<<ans<<endl; else cout<<"No solution"<<endl; } }