没想到还会回来写博客,算是回忆下把,来一道区间dp基础题。
题意:一个送外卖的从某个出发点送外卖,但是每个顾客地点都有一个不满意值,会随着时间每秒增加b[i],每个顾客地点都有一个距离,可以人为是在x轴上的坐标。现在问如何送外卖使得不满意度最小。
题解:好像做过,不过这次换了一个更优美的姿势过,记忆优化写起来会比较好写,而且姿势优美。
dp[i][j][pos]表示[l,r]区间的顾客都送完了现在位于pos位置,pos==0表示在左边,pos==1表示在右边。
每次可以选择往区间左端或这右端走。
#include
using namespace std;
typedef long long ll;
const ll INF = 0x3f3f3f3f3f3f3f3f;
const int maxn = 1005;
ll dp[maxn][maxn][2];
int vis[maxn][maxn][2];
ll sum[maxn];
struct Node{
int x,b;
}a[maxn];
int n, X, V;
void cmin(ll& a,ll b){
if(b < a) a = b;
}
ll dfs(int l,int r,int pos){
if(l==1 && r==n) return 0;
if(vis[l][r][pos]) return dp[l][r][pos];
ll res=INF;
int cost = sum[n]-sum[r] + sum[l-1] - sum[0];
if(pos==0){
if(l-1>=1)
cmin(res, dfs(l-1,r,0) + (a[l].x-a[l-1].x)*cost);
if(r+1<=n)
cmin(res, dfs(l,r+1,1) + (a[r+1].x-a[l].x)*cost);
}
else{
if(l-1>=1)
cmin(res, dfs(l-1,r,0) + (a[r].x-a[l-1].x)*cost);
if(r+1<=n)
cmin(res, dfs(l,r+1,1) + (a[r+1].x-a[r].x)*cost);
}
vis[l][r][pos]=1;
return dp[l][r][pos]=res;
}
bool cmp(const Node& n1, const Node& n2){
return n1.x