LuoguP5075 [JSOI2012]分零食

博客介绍了LuoguP5075题目,即如何将糖果分给若干人以获得最大欢乐值的问题。通过建立动态规划模型,利用转移方程优化算法,将复杂度从(O(Am^2))降低到(O(m^2)),并最终通过了时间限制。
摘要由CSDN通过智能技术生成

题意

\(A\)个人,\(m\)个糖,你可以选择一个\(k\),使第\(1\)~\(k\)个人每个人至少得到一个糖,并且第\(k+1\)~\(A\)个人都得不到糖。\(m\)个糖必须给完。对于每个方案都有一个欢乐值,欢乐值=\(\prod_{i=1}^kOx_i^2+Sx_i+U\),其中\(OSU\)都是给定的系数,\(x_i\)为第\(i\)个人拿到的糖的数量。求所有方案的欢乐值的和。

这题不用NTT啊......
有个比较naive的\(dp\):设\(f_{i,j}\)表示前\(i\)个人一共拿到了\(j\)个糖的所有方案的欢乐值之和,那么有转移方程:

\[ f_{i,j}=\sum_{k=1}^{j-i+1}f_{i-1,j-k}\times(Ok^2+Sk+U) \]

初始值可以设\(f_{0,0}=1\)。这个\(dp\)的复杂度就是\(O(Am^2)\)。一个优化就是,由于最多前\(m\)个人拿到糖(每个人至少拿一个糖),所以\(i\)只用枚举到\(min(m,A)\),复杂度为\(O(m^3)\)
观察转移方程的结构,可以发现这样一个优化:

\[ f_{i,j-1}=\sum_{k=1}^{j-i}f_{i-1,j-1-k}\times(Ok^2+Sk+U)\\ =\sum_{k=2}^{j-i+1}f_{i-1,j-k}\times[O(k-1)^2+S(k-1)+U]\\ =\sum_{k=2}^{j-i+1}f_{i-1,j-k}\times(Ok^2+Sk+U)- \sum_{k=2}^{j-i+1}f_{i-1,j-k}\times(2Ok-O+S)\\ =f_{i,j}-f_{i-1,j-1}\times(O+S+U)- \sum_{k=2}^{j-i+1}f_{i-1,j-k}\times(2Ok-O+S) \]

观察最后这个\(\sum\),设\(g_{i,j}=\sum_{k=1}^{j-i+1}f_{i-1,j-k}\times(2Ok-O+S)\);那么求\(f\)的式子可以写成:

\[ f_{i,j-1}= f_{i,j}-f_{i-1,j-1}\times(O+S+U)-g_{i,j}+f_{i-1,j-1}\times(O+S)\\ =f_{i,j}-Uf_{i-1,j-1}-g_{i,j} \]

那么\(f_{i,j}=f_{i,j-1}+Uf_{i-1,j-1}+g_{i,j}\)
\(f\)的转移变成\(O(1)\)的了。但\(g\)还是\(O(n)\)的。观察\(g\)的结构,可以类似地写出求\(g\)的优化:

\[ g_{i,j-1}=\sum_{k=1}^{j-i}f_{i-1,j-1-k}\times(2Ok-O+S)\\ =\sum_{k=2}^{j-i+1}f_{i-1,j-k}\times[2O(k-1)-O+S]\\ =\sum_{k=2}^{j-i+1}f_{i-1,j-k}\times(2Ok-O+S)- \sum_{k=2}^{j-i+1}f_{i-1,j-k}\times 2O\\ =g_{i,j}-f_{i-1,j-1}\times(O+S)- \sum_{k=2}^{j-i+1}f_{i-1,j-k}\times 2O \]

观察最后这个\(\sum\),设\(h_{i,j}=\sum_{k=1}^{j-i+1}f_{i-1,j-k}\times 2O\);那么求\(g\)的式子可以写成:

\[ g_{i,j-1}= g_{i,j}-f_{i-1,j-1}\times(O+S)-h_{i,j}+f_{i-1,j-1}\times 2O\\ =g_{i,j}-f_{i-1,j-1}\times(S-O)-h_{i,j} \]

那么\(g_{i,j}=g_{i,j-1}+f_{i-1,j-1}\times(S-O)+h_{i,j}\)
每个\(g\)也可以\(O(1)\)求了,而且注意到\(h\)就是前缀和,每个\(h\)也可以\(O(1)\)求,所以整个\(dp\)被优化到了\(O(m^2)\)
可以通过吗?时间上,复杂度虽然是\(O(m^2)\)的,但实际上由于\(i\leq j\),所以只需要循环\(\frac{m\times(m+1)}{2}\)次,也就是\(5\times 10^7\)级别,是可以过的。空间上,加上滚动数组优化也能过。
#include<bits/stdc++.h>
#define rg register
#define il inline
#define cn const
#define gc getchar()
#define fp(i,a,b) for(rg int i=(a),ed=(b);i<=ed;++i)
using namespace std;
typedef cn int cint;
il int rd(){
   rg int x(0),f(1); rg char c(gc);
   while(c<'0'||'9'<c){ if(c=='-') f=-1; c=gc; }
   while('0'<=c&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=gc;
   return x*f;
}
template<typename T> il void ckmin(T &x,cn T &y){ if(x>y)x=y; }
cint maxn=10010;

int A,m,mod,O,S,U,ff,gg,hh,ans;
int f[2][maxn],g[2][maxn],h[2][maxn],pv=0,nw=1;

int main(){
    m=rd(),mod=rd(),A=rd(),O=rd(),S=rd(),U=rd();
    ff=U,gg=(S-O+mod)%mod,hh=(O<<1)%mod;
    
    f[0][0]=1;
    fp(i,1,min(m,A)){
        h[nw][i-1]=g[nw][i-1]=f[nw][i-1]=0;
        fp(j,i,m){
            h[nw][j]=(h[nw][j-1]+hh*f[pv][j-1])%mod;
            g[nw][j]=(g[nw][j-1]+gg*f[pv][j-1]+h[nw][j])%mod;
            f[nw][j]=(f[nw][j-1]+ff*f[pv][j-1]+g[nw][j])%mod;
        }
        ans=(ans+f[nw][m])%mod;
        nw^=pv^=nw^=pv;
    }
    printf("%d",ans);
    return 0;
}
基于SSM框架的智能家政保洁预约系统,是一个旨在提高家政保洁服务预约效率和管理水平的平台。该系统通过集成现代信息技术,为家政公司、家政服务人员和消费者提供了一个便捷的在线预约和管理系统。 系统的主要功能包括: 1. **用户管理**:允许消费者注册、登录,并管理他们的个人资料和预约历史。 2. **家政人员管理**:家政服务人员可以注册并更新自己的个人信息、服务类别和服务时间。 3. **服务预约**:消费者可以浏览不同的家政服务选项,选择合适的服务人员,并在线预约服务。 4. **订单管理**:系统支持订单的创建、跟踪和管理,包括订单的确认、完成和评价。 5. **评价系统**:消费者可以在家政服务完成后对服务进行评价,帮助提高服务质量和透明度。 6. **后台管理**:管理员可以管理用户、家政人员信息、服务类别、预约订单以及处理用户反馈。 系统采用Java语言开发,使用MySQL数据库进行数据存储,通过B/S架构实现用户与服务的在线交互。系统设计考虑了不同用户角色的需求,包括管理员、家政服务人员和普通用户,每个角色都有相应的权限和功能。此外,系统还采用了软件组件化、精化体系结构、离逻辑和数据等方法,以便于未来的系统升级和维护。 智能家政保洁预约系统通过提供一个集中的平台,不仅方便了消费者的预约和管理,也为家政服务人员提供了一个展示和推广自己服务的机会。同时,系统的后台管理功能为家政公司提供了强大的数据支持和决策辅助,有助于提高服务质量和管理效率。该系统的设计与实现,标志着家政保洁服务向现代化和网络化的转型,为管理决策和控制提供保障,是行业发展中的重要里程碑。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值