[JZOJ4931] A

Description

有N家洗车店从左往右排成一排,每家店都有一个正整数价格Pi。
有M个人要来消费,第i个人会驶过第Ai个开始一直到第Bi个洗车店,且会选择这些店中最便宜的一个进行一次消费。但是如果这个最便宜的价格大于Ci,那么这个人就不洗车了。
请给每家店指定一个价格,使得所有人花的钱的总和最大。
所有数据满足N<=50,M<=4000,1<=Ai<=Bi<=N,1<=Ci<=500000
本题开O2

Solution

既然开了O2,那就要有梦想。

考虑区间DP

首先显然每家洗车店取值只有4000种
f[l][r][i] 表示 [l,r] 内,最小值为 i 的贡献,并且有贡献的区间要全部在[l,r]内。

然后再设 g[i][j] 表示 [l,r] 条件下, i 这个位置有多少人能选j

那么 g[i][j] 可以先求,然后再转移

枚举 p ,那么f[l][r][i]可以从 f[l][p1][i],f[p+1][r][i] 转移来。(这里为了优化,我们将 i 设为i~ max 的最大值)
复杂度是 O(N3M)

然而这是能跑过的。

故曰:人不可一日无梦想

Code

#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <iostream>
#include <cstring>
#include <cmath>
#define fo(i,a,b) for(int i=a;i<=b;i++)
#define fod(i,a,b) for(int i=a;i>=b;i--)
#define LL long long 
#define N 55
#define M 4005
using namespace std;
struct node
{
    int x,y,c;
}a[M];
bool cmp(node x,node y)
{
    return x.c>y.c;
}
int n,m,f[N][N][M],g[N][M],b[N][M];
int main()
{
    cin>>n>>m;
    fo(i,1,m) scanf("%d%d%d",&a[i].x,&a[i].y,&a[i].c);
    sort(a+1,a+m+1,cmp);
    memset(f,0,sizeof(f));
    int ans=0;
    fo(len,1,n)
    {
        fo(l,1,n-len+1)
        {
            int r=l+len-1;
            memset(b,0,sizeof(b));
            fo(i,l,r)
            {
                fo(j,1,m)
                {
                    g[i][j]=0;
                    if(a[j].y==i-1&&a[j].x>=l) b[i][j]--;
                    if(a[j].x==i&&a[j].y<=r) b[i][j]++;
                    b[i][j]+=b[i-1][j];
                    g[i][j]+=g[i][j-1]+b[i][j]; 
                }
            }
            fo(i,l,r)
            {
                fo(j,1,m)
                {
                    f[l][r][j]=max(f[l][r][j],f[l][i-1][j]+f[i+1][r][j]+g[i][j]*a[j].c);
                    f[l][r][j]=max(f[l][r][j],f[l][r][j-1]);
                    ans=max(ans,f[l][r][j]);
                }
            }
        }
    }   
    cout<<ans;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值