zoj 3469 Food Delivery (区间dp)

没想到还会回来写博客,算是回忆下把,来一道区间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



你可能感兴趣的:(动态规划—区间dp,动态规划)