bzoj1564

treap,区间DP

#include<cstdio>
#include<cctype>
#include<algorithm>
using namespace std;
int n,k,cnt,dis[100],f[100][100][100];
struct data{int val,w,fre;bool operator <(const data &x)const{return val<x.val;};}tr[100];

inline int read(){
    char ch=getchar();int k=0,f=1;
    while(!isdigit(ch))ch=getchar();
    while(isdigit(ch)){k=(k<<1)+(k<<3)+ch-'0';ch=getchar();}
    return k;
}

int find(int x){
    int l=1,r=cnt;
    while(l<=r){
        int mid=(l+r)>>1;
        if(dis[mid]==x)return mid;else
        if(dis[mid]<x)l=mid+1;else
        r=mid-1;
    }
}

int dfs(int l,int r,int maxx){
    if(l>r)return 0;
    if(f[l][r][maxx]!=0)return f[l][r][maxx];
    int res=1000000008;
    for(int i=l;i<=r;i++){//区间DP
        res=min(res,dfs(l,i-1,maxx)+dfs(i+1,r,maxx)+k);
        if(tr[i].w>=maxx)res=min(res,dfs(l,i-1,tr[i].w+1)+dfs(i+1,r,tr[i].w+1));
    }
    f[l][r][maxx]=res+tr[r].fre-tr[l-1].fre;//加上该区间所有数的频度一次
    return f[l][r][maxx];
}

int main(){
    n=read();k=read();
    for(int i=1;i<=n;i++)tr[i].val=read();
    for(int i=1;i<=n;i++)dis[i]=tr[i].w=read();
    for(int i=1;i<=n;i++)tr[i].fre=read();
    sort(tr+1,tr+n+1);sort(dis+1,dis+n+1);
    cnt=unique(dis+1,dis+n+1)-(dis+1);
    for(int i=1;i<=n;i++){tr[i].w=find(tr[i].w);tr[i].fre+=tr[i-1].fre;}//离散和前缀和
    printf("%d",dfs(1,n,1));
}

 

posted @ 2018-04-18 08:58  lnyzo  阅读(80)  评论(0编辑  收藏  举报