zoukankan      html  css  js  c++  java
  • 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 }
  • 相关阅读:
    AJAX学习笔记
    JQuery 学习笔记-2017.05.22
    十二.GUI
    十一.文件
    十.模块和库
    九.类的进化(魔法方法、特性和迭代器)
    八.异常
    七.类的继承
    六.函数和类
    五.条件、循环和其他语句
  • 原文地址:https://www.cnblogs.com/Y-E-T-I/p/7762375.html
Copyright © 2011-2022 走看看