当前位置: 首页 > news >正文

RainbowDash 的旅行

D RainbowDash 的旅行 - 第七届校赛正式赛 —— 补题

题目大意:

湖中心有一座岛,湖的外围有 m m m 间木屋(围绕小岛) ,第 i i i 间木屋和小岛之间有 a i a_i ai A A A 类桥, b i b_i bi B B B 类桥, A A A 桥有车可以快速通过, B B B 桥需要步行,速度稍慢。

你计划一次 n n n 天的旅行,对于每一天,你都需要从当前木屋走到小岛游玩,再走到任何一间木屋(包括出发时所在的木屋),你不想浪费时间在赶路上,于是一天通过的两座桥必须有一座是 A A A 类桥,起始在 1 1 1 号木屋,问旅行 n n n 天,有多少不同的路线组合?

1 < = n < = 1000 , 1 < = m < = 100 1<=n<=1000,1<=m<=100 1<=n<=1000,1<=m<=100

1 < = a i , b i < = 1 0 4 1<=a_i,b_i<=10^4 1<=ai,bi<=104

思路:

考虑第 i i i 间木屋到第 j j j 间木屋有多少种方法

f [ i ] [ j ] f[i][j] f[i][j] 表示第 i i i 间木屋到第 j j j 间木屋总方案数

如果从第 i i i 间木屋去小岛走 A A A 桥,去第 j j j 间木屋则可以走 A A A 桥或者 B B B

那么方案数为 a [ i ] ∗ ( a [ j ] + b [ j ] ) a[i]*(a[j]+b[j]) a[i](a[j]+b[j])

如果从第 i i i 间木屋去小岛走 B B B 桥,去第 j j j 间木屋只可以走 A A A

方案数为 b [ i ] ∗ a [ j ] b[i]*a[j] b[i]a[j]

int f[M][M];
for(int i=1;i<=m;i++){
    for(int j=1;j<=m;j++){
        f[i][j]=a[i]*(a[j]+b[j])+b[i]*a[j];
    }
}

有了第 i i i 间木屋到第 j j j 间木屋总方案数,可以考虑 1 − n 1-n 1n 天总方案数的 d p dp dp

考虑第 k k k 天到达 第 1 − m 1-m 1m 间木屋的的方案数

d p [ k ] [ j ] dp[k][j] dp[k][j] 表示第 k k k 天到达第 j j j 间木屋的方案数

对于第 k k k 天到达第 j j j 间木屋的方案数,

考虑由第 k − 1 k-1 k1 天 从 i ( 1 − n ) i(1-n) i(1n) 间木屋转移到第 j j j 间木屋的方案数: d p [ k ] [ j ] + = d p [ k − 1 ] [ i ] ∗ f [ i ] [ j ] dp[k][j]+=dp[k-1][i]*f[i][j] dp[k][j]+=dp[k1][i]f[i][j]

第一天在1号木屋,所以第一天应由 d p [ 0 ] [ 1 ] dp[0][1] dp[0][1] 去转移,所以初始化 d p [ 0 ] [ 1 ] = 1 dp[0][1]=1 dp[0][1]=1

int dp[N][M];

for(int k=1;k<=n;k++){
    for(int i=1;i<=m;i++){
        for(int j=1;j<=m;j++){
            dp[k][j]+=dp[k-1][i]*f[i][j];
        }
    }
}

最后统计第 n n n 天到达第 1 − m 1-m 1m 间木屋总数即可

代码:

#include <bits/stdc++.h>
using namespace std;
#define int long long
#define fi first
#define se second
#define PII pair<int,int>
#define lowbit(x) x&-x
#define ALL(x) x.begin(),x.end()

const int mod = 998244353;
const int N = 100 + 10;

int f[N][N],dp[1010][N];
int a[N],b[N];
int n,m;


void solve() {
	cin>>n>>m;
	for(int i=1;i<=m;i++){
		cin>>a[i];
	}
	for(int i=1;i<=m;i++){
		cin>>b[i];
	}
	for(int i=1;i<=m;i++){
		for(int j=1;j<=m;j++){
			f[i][j]=a[i]*(a[j]+b[j])%mod+b[i]*a[j]%mod;
			f[i][j]%=mod;
		}
	}
	dp[0][1]=1;
	for(int k=1;k<=n;k++){
		for(int i=1;i<=m;i++){
			for(int j=1;j<=m;j++){
				dp[k][j]+=dp[k-1][i]*f[i][j]%mod;
				dp[k][j]%=mod;
			}
		}
	}
	int ans=0;
	for(int i=1;i<=m;i++){
		ans+=dp[n][i];
		ans%=mod;
	}
	cout<<ans<<'\n';
	
}

signed main() {
	std::ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	int T = 1;
//	cin >> T;
	while (T--) {
		solve();
	}
	return 0;
}
http://www.dtcms.com/a/108403.html

相关文章:

  • HCIP的配置
  • 使用Python和OpenCV进行指纹识别与验证
  • 通过必应壁纸官方api实现网页背景图片随机展示
  • substring() 和 slice() 这两个方法的相同与不同
  • Python 脚本:自动化你的日常任务
  • 【element ui】翻页记忆功能、多选时执行删除操作,刷新表格问题
  • VS+Qt配置QtXlsx库实现execl文件导入导出(全教程)
  • 自动调整PPT文本框内容:防止溢出并智能截断文本
  • Shiro学习(三):shiro整合springboot
  • 城电科技 | 探秘零碳校园:创新应用,引领绿色未来
  • PHP在Debian环境上的并发处理能力如何
  • 深度学习处理文本(6)
  • STM32实现一个简单电灯
  • 2023年12月电子学会青少年软件编程四级考级真题—新“跳7”游戏
  • OpenCV
  • 系统与网络安全------Windows系统安全(5)
  • Maya软件中的约束基础:提高角色动画制作效率的关键技术
  • 【解决】Edge浏览器硬件加速问题:无法滚动与卡顿的应对方法
  • Lumerical ------ Edge coupler design
  • Test——BUG篇
  • 掌握 Git 的艺术:Rebase 和 Merge 的使用技巧
  • MySQL 中 LOCK TABLES(手动锁表) 语句的详细说明,包括语法、使用场景、示例代码及注意事项
  • c加加学习之day02
  • ubuntu制做vsftpd的docker镜像
  • git总是链接不成功
  • Excel处理控件Spire.XLS系列教程:C# 打印 Excel 文档
  • 【算法】双指针
  • GIT ---- 解决【fatal: Authentication failed for】
  • 【案例89】达梦数据库优化器参数导致的SQL执行错误
  • 在Ubuntu20.04开发Dify插件教程,部署Dify插件脚手架