[COCI2009-2010#4] KABOOM
[COCI2009-2010#4] KABOOM
考虑 表示长度为 ,前 个段全部都是胶的方案总数。
这个方程显然适用于左边和右边。
我们以左边举例。
首先,如果翻折了且合法的话的话,翻完以后上边和下边显然都是有胶水的。
我们不可以从 往前面翻折,因为这个 是后面决策的中间部分,我们不可能从中间往前面翻折,所以我们考虑从 往后翻折。
上面这张图就比较清晰了,翻折完以后还是两面带胶的,相当于最开始 那一些段。
如上面这张图,表示的是把 到 这一段往后面翻折,就可以得到 这个状态,说明 ,我们要严格使得翻折以后不能超过 ,所以 应该在 之间。
但是这样的时间复杂度比较大,我们考虑优化。
由于我们采用的是翻折的操作,我们考虑从某个点翻开,也就是逆推的思路,首先要知道,逆推的思路是绝对不会对最后答案有任何影响的。
通过当前的 ,就相当于枚举 ,去进行翻开,对于 统计这个值。
在对于求和的时候,也就是翻开的时候,这时候的 是在 之间的。(从 翻开,同时不能和前面 个东西粘起来。)
然后我们就发现,这个和前面的 的这个区间(表示的是 )这个区间表示的值是差了一个 的情况,那么就是 了。
所以就有方程:
在最后统计和的时候,由于公式是非严格的,也就是说要用 来表示左边严格折到 时的方案数(这样可以保证不会统计重复),所以对于 来说(两面有胶的是不能翻折的),就有
最后输出答案就结束了。
#include<bits/stdc++.h>
using namespace std;
const int N =2000;
const int mod=10301;
int dp[N][N];
int main()
{
int n,a,b;
cin>>n>>a>>b;
for(int i=0;i<n;i++)
dp[i][i]=1;
for(int i=0;i<n;i++)
for(int j=i-1;j>=1;j--)
dp[i][j]=(dp[i][j+1]+dp[i-j][j])%mod;
int ans=0;
for(int i=a;i<=n-b;i++)
(ans+=(((dp[i][a]+mod-dp[i-1][a])%mod)*dp[n-i][b]%mod)%mod)%=mod;
cout<<ans<<endl;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 使用C#创建一个MCP客户端
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现