Prison 监狱

【题目描述】
Caima 王国中有一个奇怪的监狱,这个监狱一共有 P 个牢房,这些牢房一字排开,
第 i 个仅挨着第 i+1 个(最后一个除外)。现在正好牢房是满的。
上级下发了一个释放名单,要求每天释放名单上的一个人。这可把看守们吓得不
轻,因为看守们知道,现在牢房中的 P 个人,可以互相之间传话。如果某个人离开了,
那么原来和这个人能说上话的人,都会很气愤,导致他们那天会一直大吼大叫,搞得
看守很头疼。如果给这些要发火的人吃上肉,他们就会安静点。
现在看守们想知道,如何安排释放的顺序,才能使得他们花费的肉钱最少。
【输入格式】
第一行两个数 P 和 Q,Q 表示释放名单上的人数;
第二行 Q 个数,表示要释放哪些人。
【输出格式】
仅一行,表示最少要给多少人次送肉吃。
【数据规模】
1<=P<=1000;1<=Q<=100。
【输入样例】
20 3
3 6 14
【输出样例】
35
【注意事项】
Q<=P;且 50%的数据 1<=P<=100;1<=Q<=5。

区间dp

令f[i][j]表示释放了i~j的最小费用

f[i][j]=min(f[i][k-1]+f[k+1][j]+(a[j+1]-a[i-1]))

其实是一个逆推的过程

我们从结果f[i][i]一步步推到f[1][q]

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 #include<cmath>
 6 using namespace std;
 7 int a[1002],p,q,f[1002][1002];
 8 int main()
 9 {int i,j,k,s=0;
10   cin>>p>>q;
11   for (i=1;i<=q;i++)
12     {
13       scanf("%d",&a[i]);
14     }
15   a[q+1]=p+1;a[0]=0;
16   memset(f,127/3,sizeof(f));
17   for (i=1;i<=q;i++)
18     f[i][i]=a[i+1]-a[i-1]-2;
19   for (i=2;i<=q;i++)
20     {
21       for (j=1;j+i-1<=q;j++)
22     {
23       for (k=j;k<=j+i-1;k++)
24         {
25           s=0;
26           if (k>=j+1)
27         s+=f[j][k-1];
28           if (k<j+i-1)
29         s+=f[k+1][j+i-1];
30           s+=a[j+i]-a[j-1]-2;
31           f[j][j+i-1]=min(f[j][j+i-1],s);
32         }
33     }
34     }
35   cout<<f[1][q];
36 }

 

posted @ 2017-10-31 16:51  Z-Y-Y-S  阅读(654)  评论(0编辑  收藏  举报