Codeforces Round #370 (Div. 2)
题目链接:
做出几道说几道,QAQ
分析:
A.所要求的第i个数为输入的第i个数与第i+1个数之和,最后一个数直接输出即可
B.统计向左、向右、向上、向下步数为sum1,sum2,sum3,sum4,左右相减取绝对值得sum5,上下相减取绝对值sum6
最后取sum5和sum6的平均值,若总步数为奇则判-1
C.从y处理到x,每次选取三个数中较大的两个a,b,将c变成min(x,a+b-1)即可
D.一道难度中上的DP题,很有意思,建议做一做。
dp[i][j]表示第i轮第一个人得分为j的方案数,然后
递推求dp[i][j]时,先维护前缀和sum[i] =((i?sum[i-1]:0)+dp[i-1][j])%mod;
再更新dp[i][j]=(sum[j]-(j-2*k-1>=0?sum[j-2*k-1]:0))%mod;表示dp[i][j]=j-2*k到j的方案都ok
再维护前缀和sum[j]=((j>0?sum[j-1]:0)+dp[t][j])%mod;
最后:
假设第二个人得分为k,那么j(第一个人得分)+a>k+b k<j+a-b也就是说第一个人得分为j时方案数为dp[t][j]时第二个人满足的方案数为sum[j]-(j+a-b-1<0?0:sum(j+a-b-1),所以两者要相乘
(res += 1LL * dp[t][j] * (j + a - b - 1 < 0 ? 0 : sum[j + a- b - 1]) % mod) %= mod
详情见代码
1 #include <bits/stdc++.h> 2 #define LL long long 3 #define pii pair <int, int> 4 #define xx first 5 #define yy second 6 #define ls rt << 1 7 #define rs rt << 1 | 1 8 #define lson ls, l, m 9 #define rson rs, m + 1, r 10 using namespace std; 11 12 const int N = 210000, mod = 1e9 + 7; 13 int dp[110][N], sum[N]; 14 15 int main () { 16 // freopen ("in", "r", stdin); 17 int a, b, k, t; 18 cin >> a >> b >> k >> t;// int now = 0; 19 dp[0][0] = 1; 20 //dp[i][j]表示到第i轮得分为j的方案数 21 //先求出方案的前缀和,再求出在第i轮得分j范围内的dp[i][j]=sum[j]-sum[j-2*k-1]的总方案数 22 for (int i = 1; i <= t; i++) { 23 //for (int j = 0; j <= (2 * k) * t; j++) cout << dp[i - 1][j] << endl; 24 for (int j = 0; j < N; j++) sum[j] = ((j > 0 ? sum[j - 1] : 0) + dp[i - 1][j]) % mod; 25 for (int j = 0; j < N; j++) dp[i][j] = (sum[j] - (j - 2 * k - 1 >= 0 ? sum[j - 2 * k - 1] : 0) + mod) % mod; 26 } 27 //到达第t轮得分为j的方案数前缀和计算 28 for (int j = 0; j < N; j++) sum[j] = ((j > 0 ? sum[j - 1] : 0) + dp[t][j]) % mod; 29 // for (int j = 0; j <= (2 * k) * t; j++) cout << dp[t][j] << endl; 30 int res = 0; 31 for (int j = 0; j <= (2 * k) * t; j++) { 32 // cout << 33 (res += 1LL * dp[t][j] * (j + a - b - 1 < 0 ? 0 : sum[j + a- b - 1]) % mod) %= mod; 34 } 35 cout << res << endl; 36 // cout << res; 37 }
一直地一直地往前走