Título: F. White subárbol el máximo
significado de las preguntas: Dado un nodo de árbol sólo negro o blanco, pida a cada nodo del subárbol (bloque de comunicación) max (número de nodo blanco - el número de nodos negros);
El valor de un nodo dado es una, negro -1, es decir, se calcula el valor máximo, árbol DP, relación de contacto niño, el padre, i puede ser directamente dp raíz blanca, DP1 [i] se expresa en el i padre max abajo nodo (blanco - negro), empezando con un nodo hijo grabación DP1 make inferior-max;
allí lado del nodo padre del nodo no es bloque de comunicación máximo determinado, digamos val es el valor obtenido por el nodo padre, val <= 0 significa no cuando sea necesario para añadir valor a su nodo hijo, val> 0 cuando el valor añadido aumentó nodos secundarios, y DP1 [i] es el número negativo más grande -1 sí misma debe ser considerada, y luego añadir DP1 [root] puede ser.
#include<cmath>
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<cstdlib>
#include<istream>
#include<vector>
#include<stack>
#include<set>
#include<map>
#include<algorithm>
#include<queue>
#define MAX_len 50100*4
using namespace std;
typedef long long ll;
int a[200100];
bool vis[200100];
vector<int>hh[200100];
int dp1[200100];
int dp2[200100];
void dfs1(int root,int fa)
{
if(vis[root])
return ;
vis[root]=true;
dp1[root]=a[root];
for(int i=0;i<hh[root].size();i++)
{
int v=hh[root][i];
if(v!=fa&&!vis[v])
{
dfs1(v,root);
dp1[root]+=max(0,dp1[v]);
}
}
}
void dfs2(int root,int fa)
{
if(vis[root])
return ;
vis[root]=true;
dp2[root]=dp1[root]+max(0,dp2[fa]-max(0,dp1[root]));
for(int i=0;i<hh[root].size();i++)
{
int v=hh[root][i];
if(v!=fa&&!vis[v])
{
dfs2(v,root);
}
}
}
int main()
{
int n,i,j,l,r,h;
scanf("%d",&n);
for(i=1;i<=n;i++)
{
scanf("%d",&a[i]);
if(a[i])
a[i]=1;
else
a[i]=-1;
}
for(i=1;i<=n-1;i++)
{
int x,y;
scanf("%d %d",&x,&y);
hh[x].push_back(y);
hh[y].push_back(x);
}
memset(vis,false,sizeof(vis));
dfs1(1,-1);
memset(vis,false,sizeof(vis));
dfs2(1,-1);
for(i=1;i<=n;i++)
{
printf("%d ",dp2[i]);
}
return 0;
}
Título: E. dormir la Lista
título significa: con n tiempo de sueño seleccionado puede ser seleccionado a [i] o iniciar el sueño después de un [i] -1 hora, si el período de puesta en lr sueño es un sueño bueno, un sueño h hora (es decir, un día).
¿Quieres empezar con un h [i] o un estado [i] -1 DP para llevar a cabo, pero no encontraron más casos de almacenamiento de estado, puede ser visto (h allí horas al día) no es grande estado, de dos dimensiones en h en él.
Buen sueño representa el número máximo de i-ésimo en el inicio del sueño j cuando el tiempo es: dp [i] [j] .
#include<cmath>
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<cstdlib>
#include<istream>
#include<vector>
#include<stack>
#include<set>
#include<map>
#include<algorithm>
#include<queue>
#define MAX_len 50100*4
using namespace std;
typedef long long ll;
int a[2010];
int dp[2010][2010];
int book[2010];
int main()
{
memset(book,0,sizeof(book));
memset(dp,0,sizeof(dp));
int n,i,j,l,r,h;
scanf("%d %d %d %d",&n,&h,&l,&r);
for(i=1;i<=n;i++)
scanf("%d",&a[i]);
int ans=0;
dp[0][0]=1;
for(i=1;i<=n;i++)
{
for(j=0;j<h;j++)
{
if(dp[i-1][j])
{
bool flag=false;
int temp;
temp=(j+a[i])%h;
if(temp>=l&&temp<=r)
dp[i][temp]=max(dp[i][temp],dp[i-1][j]+1);
else
dp[i][temp]=max(dp[i][temp],dp[i-1][j]);
temp=(j+a[i]-1)%h;
if(temp>=l&&temp<=r)
dp[i][temp]=max(dp[i][temp],dp[i-1][j]+1);
else
dp[i][temp]=max(dp[i][temp],dp[i-1][j]);
}
}
}
for(i=0;i<h;i++)
ans=max(ans,dp[n][i]);
printf("%d",ans-1);
return 0;
}