bzoj 4380: [POI2015]Myjnie 动态规划

来源:互联网 发布:数据挖掘十大算法答案 编辑:程序博客网 时间:2024/05/21 10:55

       感谢Claris的题解

       令t[l][r][x]表示l~r家店,最小的价格为x时,对于所有l<=a[i],b[i]<=r的顾客的最大收入;令f[l][r][x]表示最大收入时最小那家店的位置;同时令g[l][r][x]表示l~r家店,最小的价格>=x的最大收入,同时令pos[l][r][x]表示最小的价格的店。然后就是O(N^3M)了。

AC代码如下:

#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>#define N 55#define M 4005using namespace std;int n,m,cnt,ans[N],pos[N][N][M],f[N][N][M],g[N][N][M],s[N][M],a[M],b[M],c[M],num[M];int find(int x){int l=1,r=cnt,mid;while (l<r){mid=(l+r)>>1;if (num[mid]<x) l=mid+1; else r=mid;}return l;}void solve(int l,int r,int k){if (l>r) return;int t=pos[l][r][k],mid=f[l][r][t];ans[mid]=num[t]; solve(l,mid-1,t); solve(mid+1,r,t);}int main(){scanf("%d%d",&n,&m); int i,j,k,x;for (i=1; i<=m; i++){scanf("%d%d%d",&a[i],&b[i],&c[i]);num[i]=c[i];}sort(num+1,num+m+1);cnt=1;for (i=2; i<=m; i++)if (num[i]!=num[cnt]) num[++cnt]=num[i];for (i=1; i<=m; i++) c[i]=find(c[i]);for (i=n; i; i--) for (j=i; j<=n; j++){for (k=i; k<=j; k++) memset(s[k],0,sizeof(s[k]));for (k=1; k<=m; k++) if (i<=a[k] && b[k]<=j)for (x=a[k]; x<=b[k]; x++)s[x][c[k]]++;for (k=i; k<=j; k++)for (x=cnt-1; x; x--) s[k][x]+=s[k][x+1];for (x=cnt; x; x--){int mx=0,tmp;for (k=i; k<=j; k++){tmp=g[i][k-1][x]+g[k+1][j][x]+s[k][x]*num[x];if (tmp>=mx){mx=tmp; f[i][j][x]=k;}}if (mx>=g[i][j][x+1]){ g[i][j][x]=mx; pos[i][j][x]=x; }else{ g[i][j][x]=g[i][j][x+1]; pos[i][j][x]=pos[i][j][x+1]; }}}printf("%d\n",g[1][n][1]);solve(1,n,1);for (i=1; i<n; i++) printf("%d ",ans[i]);printf("%d\n",ans[n]);return 0;}



by lych

2016.3.28

0 0
原创粉丝点击