zoukankan      html  css  js  c++  java
  • [BZOJ4897][THUSC2016]成绩单(DP)

    4897: [Thu Summer Camp2016]成绩单

    Time Limit: 40 Sec  Memory Limit: 512 MB
    Submit: 220  Solved: 132
    [Submit][Status][Discuss]

    Description

    期末考试结束了,班主任L老师要将成绩单分发到每位同学手中。L老师共有n份成绩单,按照编号从1到n的顺序叠
    放在桌子上,其中编号为i的成绩单分数为w_i。成绩单是按照批次发放的。发放成绩单时,L老师会从当前的一叠
    成绩单中抽取连续的一段,让这些同学来领取自己的成绩单。当这批同学领取完毕后,L老师再从剩余的成绩单中
    抽取连续的一段,供下一批同学领取。经过若干批次的领取后,成绩单将被全部发放到同学手中。然而,分发成绩
    单是一件令人头痛的事情,一方面要照顾同学们的心理情绪,不能让分数相差太远的同学在同一批领取成绩单;另
    一方面要考虑时间成本,尽量减少领取成绩单的批次数。对于一个分发成绩单的方案,我们定义其代价为:
    其中,k是方案中分发成绩单的批次数,对于第i批分发的成绩单,〖max〗_i是最高分数,〖min〗_i是最低分数。
    a,b是给定的评估参数。现在,请你帮助L老师找到代价最小的分发成绩单的方案,并将这个最小的代价告诉L老师
    。当然,分发成绩单的批次数k是由你决定的。

     

    Input

    第一行包含一个正整数n,表示成绩单的数量。
    第二行包含两个非负整数a,b,表示给定的评估参数。
    第三行包含n个正整数w_i,表示第i张成绩单上的分数。

     

    Output

    仅一个正整数,表示最小的代价是多少。

     

    Sample Input

    10
    3 1
    7 10 9 10 6 7 10 7 1 2

    Sample Output

    15
    【样例数据说明】
    第1批:第2至4份成绩单,落差值为1,剩余成绩单为76710712;
    第2批:第4份成绩单,落差值为0,剩余成绩单为767712;
    第3批:第1至4份成绩单,落差值为1,剩余成绩单为12;
    第4批:剩余的2份成绩单,落差值为1。
    总代价为4×3+(1^2+0^2+1^2+1^2)×1=15。

    HINT

     

     n<=50, a<=100, b<=10, w_i<=1000

     

    Source

    [Submit][Status][Discuss]

    应该是很久之前就有的原题,好像还是DP入门题,但是并不好想。

    明显的区间DP,f[i][j]表示i到j的最小代价。

    发现无法直接转移,考虑加上辅助数组。注意到每次操作的代价只与max-min有关,且数据范围中数值最大值很小,可以判断新数组与max和min有关。

    设f[i][j][l][r]表示在[i,j]区间中,最后一次取的子序列的数值范围在[l,r]中(且最后一次取的子序列包含j)的方案数。

    f的转移可以考虑最后一个数和哪些序列一起被删除(显然在此区间中最后一个数一定是最后一个被删的)。

    g的转移可以考虑最后一次操作的子序列最后一个数是哪个,直接暴力转移即可。复杂度$O(n^5)$

     1 #include<map>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 #define rep(i,l,r) for (int i=l; i<=r; i++)
     6 typedef long long ll;
     7 using namespace std;
     8 
     9 const int N=52;
    10 int n,A,B,mx,a[N],b[N],f[N][N][N][N],g[N][N],d[N],s[N];
    11 map<int,int>h;
    12 
    13 int main(){
    14     freopen("bzoj4897.in","r",stdin);
    15     freopen("bzoj4897.out","w",stdout);
    16     scanf("%d%d%d",&n,&A,&B);
    17     rep(i,1,n) scanf("%d",&a[i]),d[i]=a[i];
    18     sort(d+1,d+n+1);
    19     rep(i,1,n) if (d[i]!=d[i-1] || i==1) s[h[d[i]]=++mx]=d[i];
    20     rep(i,1,n) b[i]=h[a[i]];
    21     memset(f,0x3f,sizeof(f)); memset(g,0x3f,sizeof(g));
    22     rep(i,1,n) f[i][i][b[i]][b[i]]=0,g[i][i]=A,g[i][i-1]=0;
    23     g[n+1][n]=0;
    24     rep(L,2,n)
    25         for (int l=1,r; (r=l+L-1)<=n; l++){
    26             f[l][r][b[r]][b[r]]=g[l][r-1];
    27             rep(i,l,r-1) rep(j,1,mx) rep(k,j,mx){
    28                 int tj=min(j,b[r]),tk=max(k,b[r]);
    29                 f[l][r][tj][tk]=min(f[l][r][tj][tk],f[l][i][j][k]+g[i+1][r-1]);
    30             }
    31             rep(i,l,r) rep(j,1,mx) rep(k,j,mx)
    32                 g[l][r]=min(g[l][r],f[l][i][j][k]+g[i+1][r]+A+B*(s[k]-s[j])*(s[k]-s[j]));
    33         }
    34     printf("%d
    ",g[1][n]);
    35     return 0;
    36 }
  • 相关阅读:
    Records of Pytorch in Practice
    fast.ai Lesson 2: Deep Learning 2018
    fast.ai Lesson 1: Deep Learning 2018
    Learn You a PyTorch! (aka Introduction Into PyTorch)
    Deep RL Bootcamp Frontiers Lecture I: Recent Advances,
    Deep RL Bootcamp TAs Research Overview
    Deep RL Bootcamp Lecture 10B Inverse Reinforcement Learning
    Deep RL Bootcamp Lecture 9 Model-based Reinforcement
    Deep RL Bootcamp Lecture 8 Derivative Free Methods
    Deep RL Bootcamp Lecture 7: SVG, DDPG, and Stochastic Computation Graphs
  • 原文地址:https://www.cnblogs.com/HocRiser/p/8948211.html
Copyright © 2011-2022 走看看