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 }
  • 相关阅读:
    主从数据库
    Linux 安装 mysql
    centos7.5上安装go1.13.4
    Linux 安装php
    CENTOS7下安装redis
    CentOS 7安装Etherpad(在线协作编辑)
    nginx《一安装》
    springboot中redis取缓存类型转换异常
    linux安装mysql
    linux上传下载文件(转载https://www.jb51.net/article/143112.htm)
  • 原文地址:https://www.cnblogs.com/Y-E-T-I/p/7762375.html
Copyright © 2011-2022 走看看