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 ...
随机推荐
- 并不对劲的P5589
题目大意 有\(n\)(\(n\leq 10^9\))个数:\(1,2,...,n\),每次操作是随机取一个没被删除的数\(x\),并删去\(x,x^2,x^3,...\). 求期望几次删完所有数. ...
- Asp.net core Identity + identity server + angular + odata + 权限管理
今天踩了一个坑. 网站发布后看到了一个 error Refused to execute inline script because it violates the following Content ...
- 深入理解计算机系统 第十章 系统级I/O 第二遍
了解 Unix I/O 的好处 了解 Unix I/O 将帮助我们理解其他的系统概念 I/O 是系统操作不可或缺的一部分,因此,我们经常遇到 I/O 和其他系统概念之间的循环依赖.例如,I/O 在进程 ...
- date和time
time和date两个函数在Lua中实现所有的时钟查询功能.函数time在没有参数时返回当前时钟的数值. t=os.date()print(t) 05/07/19 16:49:18 --------- ...
- 8-Perl 哈希
1.Perl 哈希哈希是 key/value 对的集合.Perl中哈希变量以百分号 (%) 标记开始.访问哈希元素格式:${key}.以下是一个简单的哈希实例:#!/usr/bin/perl%data ...
- SQL SERVER中Datetime时间的范围与.net的DateTime对象的区别
对于编写.net程序中我们一般写默认的时间,我们会自动创建一个new DateTime()对象.但与SQL SERVER连用我们就会出现一个时间范围的问题. 今天我就记录一下该时间问题. 我们创建的n ...
- 使用webpack + momentjs时, 需要注意的问题
注意开发HTML页面charset, 如是不是utf-8, 比如是shift_jis, 一般会在webpack里用插件EncodingPlugin把开发的utf-8格式转码成shift_jis格式 ...
- 常用的Java工具类——十六种
常用的Java工具类——十六种 在Java中,工具类定义了一组公共方法,这篇文章将介绍Java中使用最频繁及最通用的Java工具类.以下工具类.方法按使用流行度排名,参考数据来源于Github上随机选 ...
- Oracle的FIXED
今天发现一个有意思的问题,我们知道,在Oracle数据库中正常执行 select sysdate from dual 都可以返回当前主机的系统时间.正常修改系统时间,对应的查询结果也会变成修改后的系统 ...
- tp5.1 nginx配置
解决方案 修改fastcgi的配置文件 目录:/www/server/nginx/conf/fastcgi.conf fastcgi_param PHP_ADMIN_VALUE "op ...