比赛结束了几天...这篇博客其实比完就想写了...但是想等补完可做题顺便po上题解...
5.10晚的动车到了济南,没带外套有点凉。酒店还不错。
5.11早上去报道,济南大学好大啊...感觉走了一个世纪才到了他们的教学楼...跟我们学校比起来...
中午吃的他们的八食堂,对于我来说并没有吃饱,食堂看着很好但是给队员的窗口只有一个。其他的都没办法吃。
下午热身赛AB水题。C题刚开始觉得是二分,中途发现二分是错的然后改了几发过了之后就走了。出来之后才看的D,才知道为啥要放弃D了233
晚上吃饭吃得有点晚赶不回去打Atcoder。回到酒店后躺了会床。洗完澡11点多了就把Atcoder的ABCD切了,12点多就上床睡了(主要是E题不会写。待会去补。
第二天比赛,拿到题册后想着要抢一发一血,先开的A题,一紧张写WA了。改了一下才过的。之后看了下D发现跟图无关,可以直接写就一发过了。
然后我就贡献了3发H的罚时啦。然后就没啦。全靠队友带躺走进金牌区。封榜后看出E的ans怎么统计但是就是不知道用啥数据结构维护。算是比较遗憾的啦。
其实我很不想被人带躺。进了金牌区我并不觉得很开心甚至觉得很丢脸。因为我对队伍的贡献就只有傻逼的罚时和一两道签到题。还是得变强啊。
定位:签到
题意:重新定义了一年有12个月,1个月有30天,一周只有5天。给出一个年月日加上它的星期数,求另外一个年月日是星期几。
思路:求出两个日期之间的天数差,然后把星期几给加上这个差再mod 5就好了。注意负数的情况。比赛的时候想复杂了。还分类讨论了。。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
![](https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif)
#include <bits/stdc++.h> #define ll long long using namespace std; const char s[5][20] = { "Monday", "Tuesday", "Wednesday", "Thursday", "Friday"}; char str[20]; int main() { int T; scanf("%d", &T); while (T--) { ll a, b, c, d, e, f; scanf("%lld%lld%lld", &a, &b, &c); scanf("%s", str); scanf("%lld%lld%lld", &d, &e, &f); ll sum1 = a * 30 * 12 + b * 30 + c; ll sum2 = d * 30 * 12 + e * 30 + f; ll temp = sum2 - sum1; ll id = 0; for (int i = 0; i < 5; i++) { if (strcmp(str, s[i]) == 0) { id = i; break; } } id += temp; id %= 5; while (id < 0) id += 5; puts(s[id]); } return 0; }
定位:DP,组合数学,难
比赛的时候完全不懂。
题意:两个长度为n的01串分别为初态和末态,要求操作K轮,每轮操作m次,每次是把0变成1或者1变成0,要求从初态到末态有多少种方案。
思路:问题可以进一步简化,只要看初末有多少个字符不同,设为x。
$dp\left[ p\right] \left[ i\right]$表示在第$p$轮里有$i$个字符不同要变成相同的方案数
转移方程就是下面这样
$dp\left[ p\right] \left[ i\right] =\sum ^{\min \left( i,m\right) }_{j}C_{i}^{j} C_{n-i}^{m-j}dp\left[ p-1\right] \left[ i-j+m-j\right]$
初始:$dp\left[ 0\right] \left[ 0\right] = 0$ 第0轮0个需要变的方案肯定为1嘛。
对转移方程的解释是,在$i$个不同的里面挑了$j$来变成相同的,那么现在就还有$i-j$个是不同的,而在$n-i$个相同的里面挑了$m-j$个来变成不同的 所以这一轮之前需要变$i-j+m-j$个。
组合数就是由于顺序的不同导致方案数变多。其实还有一个$m-j$小于等于$n-i$的限制,但是由于组合数我只求到了相等的时候 所以比它大的时候组合数为0,答案不会受到影响。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
![](https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif)
#include <bits/stdc++.h> #define ll long long using namespace std; const int N = 200; const ll MOD = 998244353; ll C[N][N], dp[N][N]; void init() { C[0][0] = 1; C[1][0] = C[1][1] = 1; for (int i = 2; i < N; i++) { C[i][0] = 1; for (int j = 1; j <= i; j++) C[i][j] = C[i-1][j] + C[i-1][j-1], C[i][j] %= MOD; } } char num[2][N]; int main() { init(); int T; scanf("%d\n", &T); while (T--) { memset(dp, 0, sizeof(dp)); int n, m, k; scanf("%d%d%d", &n, &k, &m); int x = 0; scanf("%s", num[0]); scanf("%s", num[1]); for (int i = 0; i < n; i++) x += num[0][i] != num[1][i]; dp[0][0] = 1; for (int p = 1; p <= k; p++) { for (int i = 0; i <= n; i++) { for (int j = 0; j <= i && j <= m; j++) { dp[p][i] += dp[p - 1][i - j + m - j] * C[i][j] % MOD * C[n - i][m - j] % MOD; dp[p][i] %=