HZOJ 20190719 那一天我们许下约定(dp+组合数)
这个题目背景真的是让我想起了当年。。。
不说了,言归正传,这题,一眼看去30分暴力还是很好拿的,但我因为考试时的心态问题没有处理好细节爆了零。
30分暴力的普遍思路的复杂度应该是$O(nmd)$的,但是d的数据范围实在恐怖,根本无法AC。
30分思路看上去优化空间不是很大(但是有神犇想出了矩阵快速幂加速转移,TQL)。
我们考虑转换一下思路,首先d肯定是不能放进复杂度里的,那又要怎么转移呢,我们观察到因为最多有n块饼干,所以最多真正给她饼干的天数也就是n天,那么我们根据这个来设计状态:设$f[i][j]$表示真正给她$i$天,给了$j$块饼干的方案总数。那么我们可以的出状态转移方程即为$f[i][j]=\Sigma_{k=j-m}^{j-1}{f[i-1][k]}$,
$ans=\Sigma{f[i][n]*C_d^i}$。还是很好理解的趴,但是我们现在的dp式子的复杂度依然是$O(n^3)$的,考虑优化,后面的式子是一个区间和的形式,这样就很容易想到前缀和优化。复杂度就变成了$O(n^2)$。
还有就是这题要注意的几点:首先是d太大无法用我们平常用的方式求出,最好是将组合数公式展开约分求解。
其次就是在第二层循环里,本来应该是枚举$j$从$i$到$i*(m-1)$,但是前缀和要处理到$n$,因为你的前缀和是要为下一层服务的,而下一层很可能要用到$n$,所以前缀和一定要处理到$n$。
优化dp的题之前还是做的不多,这题也算练练吧。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<queue>
#include<vector>
#define int long long
#define ll long long
using namespace std;
const int N=;
const int mod=;
int dp[N][N],sum[N][N],inv[N];
int qpow(int a,int b){
int ans=;
a%=mod;
while(b){
if(b&) ans=ans*a%mod;
b>>=;
a=a*a%mod;
}
return ans;
}
/*inline int C(int a,int b){
int js=1ll,facd=1ll;
for(register int i=1;i<=b;i++) js=(js*i)%mod;
for(register int i=a-b+1;i<=a;i++) {facd=i%mod*facd%mod;cout<<"L"<<facd<<endl;}
return facd*qpow(js,mod-2)%mod;
}*/
/*inline int C(int x,int y){
int facd=1ll,faci=1ll;
x%=mod;
for(register int i=2;i<=x;++i) faci=(faci*i)%mod;
for(register int i=y-x+1;i<=y;++i) facd=i%mod*facd%mod;
int inv=qpow(faci,mod-2);
//printf("%lld %lld %lld\n",faci,facd,inv);
return facd*inv%mod;
}*/
int C(int y,int x){
if(y<0ll||x<0ll||y<x)return ;
y%=mod;
if(y==0ll||x==0ll)return ;
ll ans=;
for(int i=0ll;i<x;i++)
ans=ans*(y-i)%mod;
for(int i=1ll;i<=x;i++)
ans=ans*inv[i]%mod;
return ans;
}
signed main(){
int n,m,d;
for(int i=1ll;i<=2000ll;i++)
inv[i]=qpow(i,mod-2ll);
while(~scanf("%lld%lld%lld",&n,&d,&m)){
if(!n&&!m&&!d) break;
if(n>d*(m-)) {puts("");continue;}
memset(dp,,sizeof(dp));
memset(sum,,sizeof(sum));
for(int i=;i<m;i++){
dp[][i]=;
sum[][i]=dp[][i]+sum[][i-];
}
for(int i=m;i<=n;i++) sum[][i]=sum[][i-];
int ans=;
ans+=(dp[][n]*C(d,1ll))%mod;
for(int i=;i<=min(d,n);i++){
for(int j=i;j<=n;j++){
dp[i][j]=((sum[i-][j-]-sum[i-][max(j-m,0ll)])%mod+mod)%mod;
sum[i][j]=(sum[i][j-]+dp[i][j])%mod;
//cout<<dp[i][j]<<endl;
}
ans=(ans+dp[i][n]*C(d,i)%mod)%mod;
}
//cout<<dp[1][n]<<endl;
//for(int i=2;i<=min(d,n);i++) ans=(ans+dp[i][n]*C(d,i)%mod)%mod;
printf("%lld\n",ans%mod);
}
}
HZOJ 20190719 那一天我们许下约定(dp+组合数)的更多相关文章
- HZOI2019 A. 那一天我们许下约定 dp
题目大意:https://www.cnblogs.com/Juve/articles/11219089.html 读这道题的题目让我想起了... woc我到底在想什么?好好写题解,现在不是干那个的时候 ...
- NOIP模拟测试6「那一天我们许下约定(背包dp)·那一天她离我而去」
那一天我们许下约定 内部题,题干不粘了. $30分算法$ 首先看数据范围,可以写出来一个普通dp #include<bits/stdc++.h> #define ll int #defin ...
- HZOJ 那一天我们许下约定
比较好想的一道题,只是那个组合数比较恶心. 先说一下我最开始想的$n^4$的沙雕dp: 设f[i][j][k]为前i天给了j个,第i天给了k个,则f[i][j][k]=∑f[i-1][j-k][o]; ...
- [CSP-S模拟测试]:那一天我们许下约定(DP+组合数学)
题目传送门(内部题2) 输入格式 每个测试点有多组测试数据.对于每组数据,有一行共三个整数$N$,$D$,$M$含义如题.输入结束标识为$“0 0 0”$ (不含引号). 输出格式 对于每组数据,输出 ...
- 【模拟7.19】那一天我们许下约定(组合数学,DP)
看了题目名字深切怀疑出题人是不是失恋了,然后出题折磨我们.然后这题就愉快的打了个暴力,最后莫名其妙wa20,伤心..... 其实这题正解不是很难想,如果说把暴力的DP搞出来,正解也差不到哪去了, 我们 ...
- 一文读懂AI简史:当年各国烧钱许下的愿,有些至今仍未实现
一文读懂AI简史:当年各国烧钱许下的愿,有些至今仍未实现 导读:近日,马云.马化腾.李彦宏等互联网大佬纷纷亮相2018世界人工智能大会,并登台演讲.关于人工智能的现状与未来,他们提出了各自的观点,也引 ...
- HZOJ 20190719 那一天她离我而去(图论最小环)
这题算是这场考试里最水的一道题了吧,就是求个最小环,但之前没练过,就在考场上yy出了最短路+次短路的傻逼解法,首先是不会求次短路,其次是这显然不对呀,自己随便想想就可以反驳这种解法. 正解比较神,但是 ...
- 两个约束下的dp问题
洛谷P1510 分析:本质上还是一个01背包,将体力当做重量,体积当做价值.配上滚动数组 即dp[j]代表在体力耗费为j时最大能搬运多少体积的石头,当dp[j]>v时就说明存在满足情况的解,这样 ...
- 首次使用windows管理界面访问安装在UNIX或linux下的DP服务器时提示无权限访问的解决方法
用windwos GUI管理界面连接时提示无权限访问: 在/etc/opt/omni/server/users/userlist 添加一行: "" "*" &q ...
随机推荐
- Spring实战(十一) 在Spring XML中配置AOP
如果你没有源码,不能为通知类添加注解,又不想将AspectJ注解放入到你的代码中,必须选择XML配置了. 1.Spring XML配置文件 解析参考:http://www.cnblogs.com/bi ...
- 欧拉函数小结 hdu2588+
从费马小定理到欧拉定理 欧拉公式 再到欧拉函数.,. 小结一下欧拉函数吧 对正整数n,欧拉函数是小于n的正整数中与n互质的数的数目(φ(1)=1)----定义 欧拉函数的基本公式其中pi为x的素因子 ...
- Spring 配置文件注入
一.Spring配置文件注入 package com.zxguan.demo; public class Person { private String name; private int age; ...
- oracle数据库锁的问题
查询当前数据库被锁的对象 select b.owner,b.object_name,a.SESSION_ID,a.LOCKED_MODE from v$locked_object a dba_obje ...
- prototype,__proto__,constructor理解
prototype: 任何函数(箭头函数除外)都具有一个 prototype属性,该属性是一个对象.一般情况下只有声明function的变量才会有(自动生成)prototype这个属性,而functi ...
- linux 进程优先级 调度 nice pri
转:http://www.linuxidc.com/Linux/2016-05/131244.htm 深入 Linux 的进程优先级 [日期:2016-05-11] 来源:liwei.life 作者 ...
- 网络初级篇之VLAN(原理)
一.早期网络的问题 1.若某时刻有多个节点同时试图发送数据,极易产生冲突域,这样使得网络传输效率大大降低. 2.从一节点发送的数据都会被送到各个节点,极易形成广播域,这样会使得产生太多的广播流量而耗费 ...
- linux基础—课堂随笔08_进程(转)
进程优先级 命令 pstree -p 显示各个子线程 ps 进程状态(process state) UNIX风格:ps -ef BSD风格:ps aux 还有用到o参数,选项显示定制的信息: pid. ...
- 在RecyclerView中集成QQ汽泡一
上次已经实现了QQ汽泡的自定义View的效果[http://www.cnblogs.com/webor2006/p/7726174.html],接着再将它应用到列表当中,这样才算得上跟QQ的效果匹配, ...
- mongodb单机搭建
参考网站:http://www.runoob.com/mongodb/mongodb-linux-install.html 1.下载 https://www.mongodb.com/download- ...