BZOJ4380 POI2015 Myjnie
来源:互联网 发布:steam mac 存档 编辑:程序博客网 时间:2024/06/06 14:01
Description
有n家洗车店从左往右排成一排,每家店都有一个正整数价格p[i]。
有m个人要来消费,第i个人会驶过第a[i]个开始一直到第b[i]个洗车店,且会选择这些店中最便宜的一个进行一次消费。但是如果这个最便宜的价格大于c[i],那么这个人就不洗车了。
请给每家店指定一个价格,使得所有人花的钱的总和最大。
Input
第一行包含两个正整数
n,m(1≤n≤50,1≤m≤4000) 。接下来m行,每行包含三个正整数
a[i],b[i],c[i] (1≤a[i]≤b[i]≤n,1≤c[i]≤5×105)
Output
第一行输出一个正整数,即消费总额的最大值。
第二行输出n个正整数,依次表示每家洗车店的价格p[i],要求1<=p[i]<=500000。
若有多组最优解,输出任意一组。
Sample Input
7 5
1 4 7
3 7 13
5 6 20
6 7 1
1 2 5
Sample Output
43
5 5 13 13 20 20 13
Solution:
玄学三维dp,膜Claris大犇。
还是提醒自己先不要考虑方案输出。事实证明先考虑方案就会想到贪心爆搜等奇怪的思路上。
对于当前这个询问区间,它的贡献是
思考对象为区间的话感觉没有什么思路,我们考虑每个洗车店对答案的贡献:在什么情况下,哪些车辆会在当前的洗车店消费?
- 在某段区域内,当前这个洗车店为最小值,就会导致在该区域内并且经过该洗车店的车辆在此处进行消费。
于是我们按照上述内容进行dp就好了,定义
这样最优解就得到了,接下来打印方案的话,我们存储从哪个洗车店转移和此时洗车店的最优定价(因为我们关于dp的定义没有确定当前枚举的消费值就是最优解……)。类似二叉树一样不断将区间劈成两部分递归处理即可。对应到我的代码中分别为f数组和v数组。
最后总复杂度为
就当做是补充Claris大犇短小的题解吧2333
#include <cstdio>#include <cstring>#include <algorithm>#define N 55#define M 4005template <class temp>inline bool check_max(temp &a,temp b){ if(a>=b)return false; a=b;return true;}int dp[N][N][M],v[N][N][M],f[N][N][M],h[N][M];int a[M],b[M],c[M],res[M];int ans[M];void dfs(int l,int r,int col){ if(l>r)return; int mid=f[l][r][col]; ans[mid]=v[l][r][col]; col=v[l][r][col]; dfs(l,mid-1,col),dfs(mid+1,r,col);}int main(){ int n,m; scanf("%d %d",&n,&m); for(int i=1;i<=m;i++){ scanf("%d %d %d",&a[i],&b[i],&c[i]); res[i]=c[i]; } std::sort(res+1,res+m+1); for(int i=1;i<=m;i++) c[i]=std::lower_bound(res+1,res+m+1,c[i])-res; for(int t=1;t<=n;t++) for(int l=1;l+t-1<=n;l++){ int r=l+t-1; for(int i=l-1;i<=r;i++) for(int j=1;j<=m;j++)h[i][j]=0; for(int i=1;i<=m;i++) if(l<=a[i]&&b[i]<=r) h[a[i]][c[i]]++,h[b[i]+1][c[i]]--; for(int j=1;j<=m;j++) for(int i=l;i<=r;i++)h[i][j]+=h[i-1][j]; for(int i=l;i<=r;i++) for(int j=m;j>=1;j--)h[i][j]+=h[i][j+1]; for(int k=m;k>=1;k--){ f[l][r][k]=l,v[l][r][k]=k; for(int i=l;i<=r;i++) if(check_max(dp[l][r][k],dp[l][i-1][k]+dp[i+1][r][k]+res[k]*h[i][k])) f[l][r][k]=i,v[l][r][k]=k; } for(int k=m-1;k>=1;k--) if(check_max(dp[l][r][k],dp[l][r][k+1])) f[l][r][k]=f[l][r][k+1],v[l][r][k]=v[l][r][k+1]; } printf("%d\n",dp[1][n][1]); dfs(1,n,1); printf("%d",(!ans[1])?res[m]:res[ans[1]]); for(int i=2;i<=n;i++) printf(" %d",(!ans[i])?res[m]:res[ans[i]]); putchar('\n');}
- 【bzoj4380】[POI2015]Myjnie
- BZOJ4380[POI2015] Myjnie
- BZOJ4380 POI2015 Myjnie
- BZOJ4380: [POI2015]Myjnie
- 【jzoj4931】【bzoj4380】【POI2015】【Myjnie】【动态规划】
- BZOJ4380: [POI2015]Myjnie(区间DP)
- bzoj 4380: [POI2015]Myjnie 动态规划
- [BZOJ 4380] POI 2015 Myjnie
- POI2015 题解
- bzoj 3747: [POI2015]Kinoman
- bzoj3747【POI2015】Kinoman
- [BZOJ3747] [POI2015]Kinoman
- 【POI2015】【BZOJ4378】Logistyka
- BZOJ 3747: [POI2015]Kinoman
- BZOJ 3748: [POI2015]Kwadraty
- BZOJ4378: [POI2015]Logistyka
- BZOJ4379: [POI2015]Modernizacja autostrady
- BZOJ4381: [POI2015]Odwiedziny
- hive支持sql大全(收藏版)
- 刷新页面js中的location.reload()用法
- Windows系统使用%matplotlib inline报错
- Qt的“QStackedLayout”实现多界面切换
- 关于spring 中时间任务的配置规则
- BZOJ4380 POI2015 Myjnie
- 基于distanceTransform-距离变换的手掌中心提取
- 《构建高质量的C#代码》学习笔记
- Map中entrySet()和keySet()比较
- 榆木脑袋
- 初探接口测试框架--python系列1
- Ubuntu下 利用httpd和OpenSSL搭建HTTPS web服务器
- peda 官方帮助文档
- android app出现红叉怎么解决