zoj 3469 区间dp **

题意:有一家快餐店送外卖,现在同时有n个家庭打进电话订购,送货员得以V-1的速度一家一家的运送,但是每一个家庭都有一个不开心的值,每分钟都会增加一倍,值达到一定程度,该家庭将不会再订购外卖了,现在为了以后有更多的家庭订购,要将外卖送到的情况下使得所有用户的不开心值总和达到最小

链接:点我

很明显,每多走一分钟,没送到的家庭的不开心值都会加倍,

假设是这样的顺序123X456,从X出发先往左右中间靠近的送,再往两边送省时间

dp[i][j][0]表示从i到j用户送到最小不开心值,此时送货员停留在左边即i位置

dp[i][j][1]表示从i到j用户送到最小不开心值,此时送货员停留在右边即j位置

 

核心是访问完区间i,j,那么区间内的一定访问过了,这是区间dp的显著特征

这题比较有意思

 1 #include<cstdio>

 2 #include<iostream>

 3 #include<algorithm>

 4 #include<cstring>

 5 #include<cmath>

 6 #include<queue>

 7 #include<map>

 8 using namespace std;

 9 #define MOD 1000000007

10 const int INF=0x3f3f3f3f;

11 const double eps=1e-5;

12 typedef long long ll;

13 #define cl(a) memset(a,0,sizeof(a))

14 #define ts printf("*****\n");

15 const int MAXN=1005;

16 int n,m,tt;

17 int dp[MAXN][MAXN][2],a[MAXN],sum[MAXN],v,X;

18 struct Node

19 {

20     int x,b;

21     void in()

22     {

23         scanf("%d%d",&x,&b);

24     }

25 }node[MAXN];

26 bool cmp(Node a,Node c)

27 {

28     return a.x<c.x;

29 }

30 int main()

31 {

32     int i,j,k;

33     #ifndef ONLINE_JUDGE

34     freopen("1.in","r",stdin);

35     #endif

36     while(scanf("%d%d%d",&n,&v,&X)!=EOF)

37     {

38         for(i=1;i<=n;i++)   node[i].in();

39         n++;

40         node[n].x=X,node[n].b=0;

41         sort(node+1,node+1+n,cmp);

42         int st;

43         for(i=1;i<=n;i++)

44         {

45             if(node[i].x==X)

46             {

47                 st=i;

48                 break;

49             }

50         }

51         sum[1]=node[1].b;

52         for(i=1;i<=n;i++)

53             for(j=1;j<=n;j++)

54                 dp[i][j][0]=dp[i][j][1]=INF;

55         dp[st][st][0]=0,dp[st][st][1]=0;

56         for(i=2;i<=n;i++)

57         {

58             sum[i]=sum[i-1]+node[i].b;

59         }

60         for(i=st;i>=1;i--)

61         {

62             for(j=st;j<=n;j++)

63             {

64                 if(i==j)    continue;//这个一定要加啊

65                 dp[i][j][0]=min(dp[i][j][0],dp[i+1][j][0]+(sum[i]+sum[n]-sum[j])*(node[i+1].x-node[i].x));

66                 dp[i][j][0]=min(dp[i][j][0],dp[i+1][j][1]+(sum[i]+sum[n]-sum[j])*(node[j].x-node[i].x));

67                 dp[i][j][1]=min(dp[i][j][1],dp[i][j-1][0]+(sum[i-1]+sum[n]-sum[j-1])*(node[j].x-node[i].x));

68                 dp[i][j][1]=min(dp[i][j][1],dp[i][j-1][1]+(sum[i-1]+sum[n]-sum[j-1])*(node[j].x-node[j-1].x));

69             }

70         }

71         printf("%d\n",v*min(dp[1][n][0],dp[1][n][1]));

72     }

73 }

 

你可能感兴趣的:(ZOJ)