P1057 传球DP
链接:https://www.luogu.com.cn/problem/P1057
寒假偷懒好久了忘光光了(虽然没忘也不会)
一开始想不到怎么DP,用的DFS,结果30次递归直接十亿次操作TLE了
#include <bits/stdc++.h>
using namespace std;
typedef long long int LL;
int dp[40],n,m,cnt,head[40],stp,ans;
struct Edge{
int to,nxt;
}edge[80];
void add(int x,int y){
edge[++cnt].to=y;
edge[cnt].nxt=head[x];
head[x]=cnt;
}
void dfs(int now){
for(int i=head[now];i;i=edge[i].nxt)
{
int to=edge[i].to;
stp++;
if(stp>=m)
{
if(to==1&&stp==m) ans++;
goto lb1;
}
dfs(to);
lb1:
stp--;
}
}
int main()
{
cin>>n>>m;
for(int i=2;i<=n;i++)
{
add(i-1,i);
add(i,i-1);
}
add(1,n),add(n,1);
dfs(1);
cout<<ans;
return 0;
}
以下是正统DP做法:
#include <iostream>
using namespace std;
int dp[40][40]; // dp[i][j]表示传i次后到达j位置的方案数
int main() {
int n, m;
cin >> n >> m;
dp[0][1] = 1; // 初始状态:0次传球在位置1
for (int i = 1; i <= m; i++) { // 遍历每次传球
for (int j = 1; j <= n; j++) { // 遍历每个位置
// 当前状态由左右两个邻居的i-1次传球转移而来
int left = (j == 1) ? n : j - 1;
int right = (j == n) ? 1 : j + 1;
dp[i][j] = dp[i-1][left] + dp[i-1][right];
}
}
cout << dp[m][1]; // 传m次回到位置1的方案数
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 周边上新:园子的第一款马克杯温暖上架