BZOJ4380[POI2015] Myjnie
2016-10-14 20:52
302 查看
BZOJ4380[POI2015] Myjnie
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]<=500000)
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…
首先先对c[i]离散。
因为与这道题相关的量是区间的最小值,所以定义dp[i][j][k]表示区间[i,j]的最小值为k的最大值。再将这个dp定义扩展一下:dp[i][j][k]=max(dp[i][j][t],t∈[k,Max])。
所以再记一个pre[i][j][k]表示当前的dp[i][j][k]的”实际k值“,记一个fa[i][j][k]表示当前状态的最小值取在哪个点(用于输出方案)。
转移时:每一次用O(nm)算一个当最小值为k时,最小值在i点,可以消费的顾客数(顾客的区间被大区间完全包含)。转移方程:
dp[i][j][k]=max(cnt[pos][k]+dp[i][pos−1][k]+dp[pos+1][j][k])(pos∈[i,j])
dp[i][j][k]=max(dp[i][j][k],dp[i][j][k+1])(k=Max→0)
然后再根据pre数组和fa数组还原方案即可,复杂度O(n3m)
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]<=500000)
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…
首先先对c[i]离散。
因为与这道题相关的量是区间的最小值,所以定义dp[i][j][k]表示区间[i,j]的最小值为k的最大值。再将这个dp定义扩展一下:dp[i][j][k]=max(dp[i][j][t],t∈[k,Max])。
所以再记一个pre[i][j][k]表示当前的dp[i][j][k]的”实际k值“,记一个fa[i][j][k]表示当前状态的最小值取在哪个点(用于输出方案)。
转移时:每一次用O(nm)算一个当最小值为k时,最小值在i点,可以消费的顾客数(顾客的区间被大区间完全包含)。转移方程:
dp[i][j][k]=max(cnt[pos][k]+dp[i][pos−1][k]+dp[pos+1][j][k])(pos∈[i,j])
dp[i][j][k]=max(dp[i][j][k],dp[i][j][k+1])(k=Max→0)
然后再根据pre数组和fa数组还原方案即可,复杂度O(n3m)
#include<stdio.h> #include<iostream> #include<algorithm> #define N 55 #define M 4005 using namespace std; void Rd(int &res){ char c;res=0; while(c=getchar(),!isdigit(c)); do{ res=(res<<1)+(res<<3)+(c^48); }while(c=getchar(),isdigit(c)); } struct Node{int L,R,w;}A ; int dp [M],pre [M],fa [M],Ans ,val[M],cnt [M]; void Pf(int L,int R,int k){ k=pre[L][R][k]; int pos=fa[L][R][k]; Ans[pos]=val[k]; if(pos>L)Pf(L,pos-1,k); if(pos<R)Pf(pos+1,R,k); } int main(){ int n,m; Rd(n);Rd(m); for(int i=1;i<=m;i++){ Rd(A[i].L);Rd(A[i].R);Rd(A[i].w); val[i-1]=A[i].w; } sort(val,val+m); int sz=unique(val,val+m)-val; for(int i=1;i<=m;i++) A[i].w=lower_bound(val,val+sz,A[i].w)-val; sz--;//[0,sz] for(int L=n;L>=1;L--) for(int R=L;R<=n;R++){ for(int i=L;i<=R;i++) for(int j=0;j<=sz;j++) cnt[i][j]=0; for(int i=1;i<=m;i++){ if(A[i].L<L||A[i].R>R)continue; for(int j=A[i].L;j<=A[i].R;j++) cnt[j][A[i].w]++; } for(int i=L;i<=R;i++) for(int j=sz-1;j>=0;j--) cnt[i][j]+=cnt[i][j+1]; pre[L][R][sz]=sz; for(int k=sz;k>=0;k--){ int mx=-1,pos; for(int i=L;i<=R;i++){ int tmp1=0,tmp2=0; if(i>L)tmp1=dp[L][i-1][k]; if(i<R)tmp2=dp[i+1][R][k]; int rs=val[k]*cnt[i][k]+tmp1+tmp2; if(rs>mx)mx=rs,pos=i; } dp[L][R][k]=mx; fa[L][R][k]=pos; if(k<sz){ if(dp[L][R][k+1]>dp[L][R][k]){ dp[L][R][k]=dp[L][R][k+1]; pre[L][R][k]=pre[L][R][k+1]; }else pre[L][R][k]=k; } } } printf("%d\n",dp[1] [0]); Pf(1,n,0); for(int i=1;i<=n;i++) printf("%d%c",Ans[i]," \n"[i==n]); return 0; }
相关文章推荐
- 【bzoj4380】[POI2015]Myjnie
- BZOJ4380: [POI2015]Myjnie
- BZOJ4380: [POI2015]Myjnie
- BZOJ4380 POI2015 Myjnie
- [BZOJ 4380] POI 2015 Myjnie
- 【jzoj4931】【bzoj4380】【POI2015】【Myjnie】【动态规划】
- 【BZOJ 4380】4380: [POI2015]Myjnie (区间DP)
- 4380: [POI2015]Myjnie
- BZOJ 4380: [POI2015]Myjnie 区间dp
- BZOJ 4380 [POI2015]Myjnie | DP
- [BZOJ4380][POI2015] Myjnie 区间DP
- 【BZOJ4380】[POI2015]Myjnie 区间DP
- BZOJ 3747: [POI2015]Kinoman( 线段树 )
- 【bzoj4378】[POI2015]Logistyka
- [bzoj4378][POI2015]Logistyka
- bzoj4383: [POI2015]Pustynia
- BZOJ4377[POI2015] Kurs szybkiego czytania
- BZOJ 3750 [POI2015]Pieczęć
- BZOJ4385: [POI2015]Wilcze doły
- 【BZOJ4383】[POI2015]Pustynia 线段树优化建图