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)); }