BFS
/*
可以理解为:可选+1或者+k两种操作
从第1分钟按到第n分钟最多需要几次操作
所以枚举对象是0-n-1,多出去的值都mod了
不用bfs直接dp也可以
*/
#include <iostream>
#include <cstring>
#include <algorithm>
#include <queue>
using namespace std;
const int N = 1e5 + 10;
int d[N]; // 对0-n-1的操作次数,有点类似dp
int n, k;
void bfs()
{
memset(d, -1, sizeof d);
d[0] = 0;
queue<int> q;
q.push(0);
while (q.size())
{
auto t = q.front();
q.pop();
int a = (t + 1) % n;
if (d[a] == -1) // 如果当前位置没有走过
{
d[a] = d[t] + 1; // 状态更新+1,添加一次操作
q.push(a);
}
int b = (t + k) % n;
if (d[b] == -1)
{
d[b] = d[t] + 1;
q.push(b);
}
}
}
int main()
{
cin >> n >> k;
bfs();
int res = 0;
for (int i = 1; i <= n; i++)
res = max(res, d[i]);
cout << res;
return 0;
}
DP
/*
仔细读懂题,可以转化为:
枚举[0,n-1]区间,每步操作都要求精简,最后输出一个max的操作次数
其实类似那道将200元拆分为1,2,5面值,可以得到min张纸币数
所以在枚举每次n的过程中,能k就k,不能再1
*/
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 1e5 + 10;
int f[N];
int res;
int main()
{
int n, k;
cin >> n >> k;
f[0] = 0;
f[k % n] = 1;
for (int i = 1; i < n; i++) // 区间[1,n-1],0在上面初始化了
{
if (i % k == 0) // 能k就k
f[i] = f[i - k] + 1;
else
f[i] = f[i - 1] + 1;
}
for (int i = 0; i < n; i++)
res = max(res, f[i]);
cout << res;
return 0;
}