题解:AT_kupc2016_i 一坨日文看不懂思密达
考虑只有一次询问怎么做。
考虑 DP。设
表示接下来这个机器人是否复制至少一个。当然后者能转移的前提是
不难发现一个机器人最终的等级不会很大。升到某个级别的所花事件是一个等差数列,也就是说它的等级最大
对吗?
注意到
注意到,让等级为
那么如果
否则如果
是的。因为这等价于
这样就解决了一次询问。
考虑多次询问。
注意到最终能直接或间接转移到
所以重新令
所以答案就是
显然不对。因为还剩
然后答案为
// Problem:
// ティッシュ配り
//
// Contest: Luogu
// URL: https://www.luogu.com.cn/problem/AT_kupc2016_i
// Memory Limit: 256 MB
// Time Limit: 1000 ms
//
// Powered by CP Editor (https://cpeditor.org)
// #define tests
#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10, P = 1e9 + 7;
int q, n, c;
int f[500][N], g[500][N];
void solve() {
for (int i = 498; i; -- i )
for (int j = 1; j < N; ++ j ) {
if (j >= i * 2) {
// 生更好
f[i][j] = (f[i + 1][j - i] + f[i][j - i]) % P;
g[i][j] = (g[i + 1][j - i] + g[i][j - i]) % P;
} else {
f[i][j] = j;
g[i][j] = 1;
}
}
cin >> q;
while (q -- ) {
cin >> n >> c;
cout << (1ll * f[1][n / c] * c + 1ll * g[1][n / c] * (n % c)) % P << '\n';
}
}
signed main() {
freopen("robot.in", "r", stdin);
freopen("robot.out", "w", stdout);
ios::sync_with_stdio(0);
cin.tie(0), cout.tie(0);
int T = 1;
#ifdef tests
cin >> T;
#endif
while (T -- ) solve();
return 0;
}