1 条题解
-
0
自动搬运
来自洛谷,原作者为

bz029
11搬运于
2025-08-24 23:07:57,当前版本为作者最后更新于2025-01-05 15:49:01,作者可能在搬运后再次修改,您可在原文处查看最新版自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多
以下是正文
题目分析
有三个操作 A,B 和 C。 分别需要操作 , 和 次,自由调整操作顺序,使最后 最小。
操作 A,使 。
操作 B,使 。
操作 C,使 $n=\max(0,\left \lfloor \frac{n-1}{2} \right \rfloor)$。
做题思路
这道题先看数据,, 和 不超过 60,如果使用 dfs 暴力,其时间复杂度为 ,达到了 级别,只能通过第 1 个子任务。从而我们要使用 dp 来优化递归的过程。
dp 需要存储以下几个信息:
用了 次操作 A,用了 次操作 B,用了 次操作 C 时 最小为多少。
由此我们可以推出以下几个状态转移方程:
操作 A:$dp_{i+1,j,k}=\left \lfloor \frac{dp_{i,j,k}}{2} \right \rfloor$。
操作 B:$dp_{i,j+1,k}=\left \lfloor \frac{dp_{i,j,k}+1}{2} \right \rfloor$。
操作 C:$dp_{i,j,k+1}=\max(0,\left \lfloor \frac{dp_{i,j,k}-1}{2} \right \rfloor)$。
初始化:,其余为无限大。
目标:。
dp 时间复杂度为:。由于 ,, 同级,所以时间复杂度也为:。
AC 代码
#include <bits/stdc++.h> #define int long long //记得开long long,n<=1e18 using namespace std; int n,a,b,c,dp[70][70][70]; signed main(){ cin>>n>>a>>b>>c; memset(dp,0x3f,sizeof dp);//初始化为无穷大 dp[0][0][0]=n; for(int t=1;t<=a+b+c;t++){//一共需要操作a+b+c次 for(int i=0;i<=a;i++){ for(int j=0;j<=b;j++){ for(int k=0;k<=c;k++){ if(dp[i][j][k]==dp[65][65][65]) continue;//特判没有转移到的 dp[i+1][j][k]=min(dp[i+1][j][k],dp[i][j][k]/2); dp[i][j+1][k]=min(dp[i][j+1][k],(dp[i][j][k]+1)/2); dp[i][j][k+1]=min(dp[i][j][k+1],max((dp[i][j][k]-1)/2,0ll)); } } } } cout<<dp[a][b][c]; return 0; }管理员大大求过!!!
- 1
信息
- ID
- 11250
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 3
- 标签
- 递交数
- 0
- 已通过
- 0
- 上传者