ZOJ 3469 区间DP

来源:互联网 发布:bcd编码c语言 编辑:程序博客网 时间:2024/05/22 00:43

题意

一个人从X点出发给N个点送食物,速度为1/v,如果第xi个点的客人没有收到食物,那么他的不满意度将会增加bi每分钟。问不满意度最少为多少?

题解

很有趣的一道区间DP题,将出发点也放入点集中,排序,进行区间DP。
dp[i][j][0]代表该人在I处,I到J的所有客人都已配送完成时最少的不满意度。
dp[i][j][1]代表该人在J处,I到J的所有客人都已配送完成时最少的不满意度。
由此可以得到状态转移方程

dp[i][j][0]=min(dp[i][j][0],dp[i+1][j][0]+(nodes[i+1].x-nodes[i].x)*(lt[i]+rt[j+1]));                dp[i][j][0]=min(dp[i][j][0],dp[i+1][j][1]+(nodes[j].x-nodes[i].x)*(lt[i]+rt[j+1]));                dp[i][j][1]=min(dp[i][j][1],dp[i][j-1][0]+(nodes[j].x-nodes[i].x)*(lt[i-1]+rt[j]));                dp[i][j][1]=min(dp[i][j][1],dp[i][j-1][1]+(nodes[j].x-nodes[j-1].x)*(lt[i-1]+rt[j]));

代码

#include <iostream>#include<cstdio>#include<algorithm>#include<cstring>#include<vector>#include<cmath>#include<queue>#include<string>#include<set>#include<map>#include<bitset>#define UP(i,l,h) for(int i=l;i<h;i++)#define DOWN(i,h,l) for(int i=h-1;i>=l;i--)#define W(a) while(a)#define MEM(a,b) memset(a,b,sizeof(a))#define INF 0x3f3f3f3f#define LL long long#define MAXN 1010#define EPS 1e-10#define MOD 100000000using namespace std;struct Node {    int x,b;    bool operator <(const Node b) const {        return x<b.x;    }};Node nodes[MAXN];int dp[MAXN][MAXN][2];int lt[MAXN],rt[MAXN];int main() {    int n,v,x;    W(~scanf("%d%d%d",&n,&v,&x)) {        UP(i,0,n) {            scanf("%d%d",&nodes[i].x,&nodes[i].b);        }        nodes[n].x=x,nodes[n].b=0;        n++;        sort(nodes,nodes+n);        MEM(dp,INF);        int pos=0;        UP(i,0,n) {            if(nodes[i].x==x)                pos=i;        }        MEM(lt,0);        MEM(rt,0);        lt[0]=nodes[0].b;        UP(i,1,n) {            lt[i]=lt[i-1]+nodes[i].b;        }        rt[n-1]=nodes[n-1].b;        DOWN(i,n-1,0) {            rt[i]=rt[i+1]+nodes[i].b;        }        dp[pos][pos][0]=dp[pos][pos][1]=0;        UP(len,1,n) {            UP(i,0,n) {                int j=i+len;                if(j>=n) {                    continue;                }//                cout<<i<<" "<<j<<endl;                dp[i][j][0]=min(dp[i][j][0],dp[i+1][j][0]+(nodes[i+1].x-nodes[i].x)*(lt[i]+rt[j+1]));                dp[i][j][0]=min(dp[i][j][0],dp[i+1][j][1]+(nodes[j].x-nodes[i].x)*(lt[i]+rt[j+1]));                dp[i][j][1]=min(dp[i][j][1],dp[i][j-1][0]+(nodes[j].x-nodes[i].x)*(lt[i-1]+rt[j]));                dp[i][j][1]=min(dp[i][j][1],dp[i][j-1][1]+(nodes[j].x-nodes[j-1].x)*(lt[i-1]+rt[j]));            }        }//        cout<<dp[0][n][0]*v<<" "<<dp[0][n][1]*v<<endl;        printf("%d\n",min(dp[0][n-1][0]*v,dp[0][n-1][1]*v));    }}/*5 1 51 12 23 34 45 5*/