P8096 [USACO22JAN] Drought G
由于按了 Command+Q 导致没能晋级的选手报到
大眼观察,
显然我们有一个状态是“当前处理到第
也就是说,还有两个状态分别是牛
仔细考虑,容易发现其实我们只关心这两个值的差值。对于整个 DP 过程而言
那么规定
- 前
i - 1 头牛饥饿值为 0(注意:在减去k 的意义下); - 第
i 头牛饥饿值为j 。
考虑转移,由于考虑
边界为
可以通过处理前缀和的方式
最后输出
对于样例
冷静分析题目,发现题目问的是有多少种初始情况,而不是有多少种方案。当
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<queue>
#include<vector>
using namespace std;
inline int mmin(register int x, register int y) {
return x > y ? y : x;
}
const long long mod = 1000000007;
int n;
int a[107], mn = 1000;
long long ans, g[107][1007];
signed main() {
scanf("%d", &n);
for(int i = 1; i <= n; ++i) {
scanf("%d", a + i);
mn = mmin(mn, a[i]);
}
for(int i = 0; i <= a[1]; ++i) g[1][i] = i + 1; //这里省略了求和
if(n % 2 == 0)mn = 0;
for(int d = 0; d <= mn; ++d) {
for(int i = 2; i <= n; ++i) {
g[i][0] = g[i - 1][mmin(a[i], a[i - 1]) - d];
for(int j = 1; j <= a[i] - d; ++j) {
g[i][j] = g[i][j - 1] + g[i - 1][mmin(a[i] - j, a[i - 1]) - d];
if(g[i][j] >= mod) g[i][j] -= mod;
}
}
ans += g[n][0]; if(ans >= mod) ans -= mod;
}
printf("%lld\n", ans);
return 0;
}