好久没写博客了。。。。。在家的学习效率太低了,啥时候能开学啊啊啊啊啊!!
E. Sleeping Schedule
题意 一个人 每次睡觉都是一天 然后每天有h小时
然后每天睡n次 每一次醒来都有过a[i] 或 a[i]-1小时后在睡,问 在l-r小时睡觉次数最多是多少?从0点开始第一次醒来。
比赛的时候没写出来。。。
思路:如果不用dp那么很多就想 我第一次在a[i],a[i]-1的时候睡,然后每次两种情况然后总共2的n次方中复杂度肯定是不够的,但是 h最大也就2000,所以我们可以dp[i][j]表示第i次在j时开始睡
那么 我们要初始化为负无穷大 然后让dp[0][0] = 0;
代码:
#include<bits/stdc++.h>
using namespace std;
const int N = 2007;
long long dp[N][N];
long long a[N], n, h, l, r;
int main(){
scanf("%lld%lld%lld%lld",&n, &h, &l, &r);
for(int i = 1; i <= n; i++){
scanf("%lld", &a[i]);
}
memset(dp,-0x3f3f3f3f,sizeof(dp));
dp[0][0] = 0;
for(int i = 1; i <= n; i++){
for(int j = 0 ; j <= h ;j++){
if((j + a[i]) % h >= l && (j + a[i]) % h <= r){
dp[i][(j + a[i]) % h] = max(dp[i][(j + a[i]) % h], dp[i - 1][j] + 1);
}else{
dp[i][(j + a[i]) % h] = max(dp[i][(j + a[i]) % h], dp[i - 1][j]);
}
a[i]--;
if((j + a[i]) % h >= l && (j + a[i]) % h <= r){
dp[i][(j + a[i]) % h] = max(dp[i][(j + a[i]) % h], dp[i - 1][j] + 1);
}else{
dp[i][(j + a[i]) % h] = max(dp[i][(j + a[i]) % h], dp[i - 1][j]);
}
a[i]++;
}
}
long long ans = 0;
for(int i = 0; i < h; i++){
ans = max (ans, dp[n][i]);
}
printf("%lld\n", ans);
}
F. Maximum White Subtree
题意:有一颗树每个节点有颜色 (白,黑),然后让你求以每个节点为根的子树中白-黑最大是多少?
题解 :这题一看就是dp,
我们可以设dp[i]表示以i为根节点然后 向下的连通图中最大值。
然后在dfs一遍求 设 u为父亲节点 v为儿子节点
如果 dp[v] > 0 那么以v
为节点 的向上的联通图中最大值为dp[u] - dp[v];
如果dp[v]<=0 那最大值就是dp[u]
代码:
#include<bits/stdc++.h>
using namespace std;
const int N = 2e5 + 7;
int a[N], dp[N], n , sum[N], up[N], top[N], f[N];
vector<int> g[N];
void dfs(int u, int fa){
if(a[u] == 1)dp[u] = 1;
else dp[u] = -1;
for(int i: g[u]){
if(i == fa)continue;
dfs(i, u);
dp[u] = max(dp[i] + dp[u], dp[u]);
}
}
void dfs1(int u, int fa){
for(int i: g[u]){
if(i == fa){
continue;
}
if(dp[i] > 0 && dp[u] - dp[i] > 0 ) dp[i] += dp[u] - dp[i];
else if(dp[i] <= 0 && dp[u] > 0) dp[i] += dp[u];
dfs1(i, u);
}
}
int main(){
scanf("%d", &n);
for(int i = 1; i <= n; i++){
scanf("%d", &a[i]);
if(a[i] == 0)a[i] = -1;
}
for(int i = 1; i < n; i++){
int u, v;
scanf("%d%d", &u, &v);
g[u].push_back(v);
g[v].push_back(u);
}
dfs(1, 0);
dfs1(1, 0);
for(int i = 1; i <= n; i++){
printf("%d ", dp[i]);
}
puts("");
}