vjudge contest 4、5;
心得:dp和数论是最基础的技能,但是最近的两次复习作业表,做起来感觉力不从心,很多dp的技巧,数论的知识都开始遗忘了,加上最近的生活作息不正常,又有新高一的dailao的加入,感觉很有压力,做题完全提不起劲
DP
区间DP环形DP
背包DP+biset压位优化:V4 J;
题目简化:
他会准备N带有数字的卡片。上的数字一世-th 卡是 一种一世. 在课堂上,他每回合将删除不超过3 卡片,让学生选择任意十张卡片,其上的数字之和 87.
口糊 因为
d
p
[
i
]
dp[i]
dp[i]这个状态只有0/1两种状态,所以我们可将其压成一个很长的01串,当更新一个价值为
w
[
j
]
w[j]
w[j]的物品j时,我们直接将01其左移
w
[
j
]
w[j]
w[j]位并同之前的01串或起来就好了,这样就很好的省掉了要去枚举i状态的时间
树形DP+换根:V4 E;
!!!
这个题目真的想了很久,但是最后还是在帮助下理清楚了思路,虽然张老板说这好像就是一个换根类树形dp的模板水题
题意简化:
有一颗有 n n n个节点的树,每个节点上有一个贡献只能被加一次,而每条边有一个代价,每次经过都需要消耗这个代价,现在让你求在每个节点出发,每次能获得的最大收益是多少
solution 口糊:我们再算一个儿子的最终答案的时候,他的父亲此时会变成他的儿子,加入计算,条件是,删除儿子对他的答案贡献;想法非常简单,但是代码实现起来,本蒟蒻太菜了,挣扎了很久才写出来
状态:
d
p
[
i
]
[
0
]
dp[i][0]
dp[i][0] 代表从i点出发但最后回到i点的最大收益
d
p
[
i
]
[
1
]
dp[i][1]
dp[i][1]不需要回到i点的最大收益
这里就是带有换根操作的dfs(总共进行了两次dfs)
void dfs2(int u, int fa, int Cost)
{
int dir = u, tmp;
if(fa&& dp[fa][0] - Cost * 2 > 0)
dp[u][0] += dp[fa][0] - Cost * 2;
tmp = dp[u][1] = dp[u][0];
for(int i = lst[u]; i; i = nex[i])
{
int v = en[i];
int mx=dp[u][0] - max(0, dp[v][0] - len[i] * 2) + (dp[v][1] - len[i]);
if(mx >= dp[u][1]) {
dir = v;
tmp=dp[u][1];
dp[u][1] = mx;
}
else if(mx >= tmp) tmp = mx;
}
int L = dp[u][0], R = dp[u][1];
for(int i = lst[u]; i; i = nex[i])
{
int v = en[i];
if(v == fa) continue;
int mx=dp[v][0] - len[i] * 2;
if(mx > 0) dp[u][0] -= mx;
if(dir==v) dp[u][1] = tmp;
if(mx > 0) dp[u][1] -= mx;
dfs2(v, u,len[i]);
dp[u][0] = L, dp[u][1] = R;
}
}
数论
大组合数取模(Lucas定理) V5 A
题意简化:
你现在有一个杨辉三角,编号都从0开始,计算从顶部开始到第 n 行第 k 列结束的路径上传递的最小数字总和。每一步都可以直接向下或向右斜向下走,如图2。数据规模 n < = 1 0 9 , p < = 1 0 4 n<=10^9,p<=10^4 n<=109,p<=104
solution: 我们可以将一个位置的最优距离转化为一个组合数,然后我们发现n的规模很大,但是我们发现模数保证是个质数并且规模很小,于是我们想到用Lucas定理来对组合数的求取变得更简单.
ll lucus(ll n,ll m,ll p){return m==0?1:C(n%p,m%p,p)*lucus(n/p,m/p,p)%p;}
矩阵计数 V5 D
题意简化:
有一个h行w列的棋盘,里面有一些格子是不能走的,现在要求从左上角走到右下角的方案数。(只能向右和向下走)
**solution:**我们将不能走的格子按照 x x x为第一关键字, y y y为第二关键字,升序排列,我们用 f [ i ] f[i] f[i]表示到i号不能走的格子,且不经过其他不能经过格子的方案数,那么转移就是 f [ i ] = C ( x + y − 2 , x − 1 ) − ∑ j = 1 i − 1 f [ i ] f[i] = C(x+y-2,x-1) - \sum_{j=1}^{i-1} f[i] f[i]=C(x+y−2,x−1)−∑j=1i−1f[i]