[LOJ2292] [THUSC2016] 成绩单

题目链接

LOJ:https://loj.ac/problem/2292

洛谷:https://www.luogu.org/problemnew/show/P5336

Solution

区间\(\rm dp\),状态比较难想...为啥网上好多仙人说这题很蠢,可能是我太菜了吧

\(f[l][r]\)表示\([l,r]\)消完的最小代价,\(g[l][r][x][y]\)表示把\([l,r]\)的值域消成\([x,y]\)的最小代价。

注意这题只需要大小关系,所以可以离散化。

转移就很好办了,先转移\(g\),枚举\(r\)号元素删不删,然后在由\(g\)转移\(f\),具体看下代码注释吧。

复杂度\(O(n^5)\)

Code

#include<bits/stdc++.h>
using namespace std;

void read(int &x) {
    x=0;int f=1;char ch=getchar();
    for(;!isdigit(ch);ch=getchar()) if(ch=='-') f=-f;
    for(;isdigit(ch);ch=getchar()) x=x*10+ch-'0';x*=f;
}

void print(int x) {
    if(x<0) putchar('-'),x=-x;
    if(!x) return ;print(x/10),putchar(x%10+48);
}
void write(int x) {if(!x) putchar('0');else print(x);putchar('\n');}

#define lf double
#define ll long long 

#define pii pair<int,int >
#define vec vector<int >

#define pb push_back
#define mp make_pair
#define fr first
#define sc second

#define FOR(i,l,r) for(int i=l,i##_r=r;i<=i##_r;i++) 

const int maxn = 55;
const int inf = 1e9;
const lf eps = 1e-8;
const int mod = 1e9+7;

int f[55][55],g[55][55][55][55],v[maxn],t[maxn],n,a,b,m;

void init() {   
    read(n),read(a),read(b);
    FOR(i,1,n) read(v[i]),t[i]=v[i];
    sort(t+1,t+n+1);m=unique(t+1,t+n+1)-t-1;
    FOR(i,1,n) v[i]=lower_bound(t+1,t+m+1,v[i])-t;
}

void chmin(int &x,int y) {if(x>y) x=y;}
void chmax(int &x,int y) {if(x<y) x=y;}

#define sqr(x) ((x)*(x))

int main() {
    init();
    memset(f,63,sizeof f);
    memset(g,63,sizeof g);
    FOR(i,1,n) {
        f[i][i]=a;
        FOR(l,1,m) FOR(r,l,m)
            if(l<=v[i]&&v[i]<=r) g[i][i][l][r]=0;
            else g[i][i][l][r]=a;   //初值注意下
    }
    for(int len=2;len<=n;len++)
        for(int l=1;l<=n-len+1;l++) {
            int r=l+len-1;
            for(int x=1;x<=m;x++)
                for(int y=x;y<=m;y++) {
                    if(x<=v[r]&&v[r]<=y) chmin(g[l][r][x][y],g[l][r-1][x][y]);   // 不删r
                    for(int k=l+1;k<=r;k++)
                        chmin(g[l][r][x][y],g[l][k-1][x][y]+f[k][r]);        // 删r,枚举包括r的区间
                    chmin(f[l][r],g[l][r][x][y]+a+b*sqr(t[y]-t[x]));      //转移f
                }
        }
    write(f[1][n]);
    return 0;
}
posted @ 2019-05-31 10:51  Hyscere  阅读(166)  评论(0编辑  收藏  举报