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 ...
随机推荐
- Flask_入门
django是个大而全的框架,flask是一个轻量级的框架. django内部为我们提供了非常多的组件:orm / session / cookie / admin / form / modelfor ...
- C# 反射遍历对象所有属性
[TestMethod] public void Test6() { List<RepaymentRecord> repaymentList = new List<Repayment ...
- c#获取桌面路径和bin文件的路径
string path = Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory): 生成的运行bin文件下的路径: ...
- JS基础_for循环练习3
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...
- Facebook团队合影
今晚公司年会,晚上有些人不去,我晚上要带孩子,也不去,大家就说那我们中午照个合照吧.没啥子准备,大家都一副油腻的样子.除了要去party的化了妆.
- mqtt协议实现 java服务端推送功能(一)安装
最近有个新需求,需要通过java服务端把信息推送到mqtt服务器上,安卓和ios端从mqtt服务器上获取信息实现推送. 1. 本地需要安装Mosquitto服务器 http://mosquitto. ...
- vue中的常用三元
点击事件的三元 <el-button type="primary" @click="edit == 'mod' ? sureModify() : submit()& ...
- JVM垃圾回收那些事
Java这种VM类跨平台语言比起C++这种传统编译型语言很大的区别之一在于引入了垃圾自动回收机制.自动垃圾回收大大提高了Java程序员的开发效率并且极大地减少了犯错的概率,但终归而言由于无法像C++程 ...
- Windows命令行命令总结
转载地址:https://www.cnblogs.com/accumulater/p/7110811.html 1. gpedit.msc-----组策略 2. sndrec32-------录音 ...
- 使用HandyJSON导致的内存泄漏问题相关解决方法
在移动开发中,与服务器打交道是不可避免的,从服务器拿到的接口数据最终都会被我们解析成模型,现在比较常见的数据传输格式是json格式,对json格式的解析可以使用原生的解析方式,也可以使用第三方的,我们 ...