本来四道题rank800+稳稳地上分,然后唯一一道1A的C题挂了终测,瞬间rank2000+,掉了49分。。。(哇)
A:给你雪球初始的重量和高度,每秒下降一米,每下降一米重量就会增加对应的高度。然后给你两个x1,h1和x2,h2表示高度h1会让雪球重量减少x1,高度h2会让雪球重量减少x2(当然还是要增加对应高度),雪球最小重量为0,求到h=0的时候雪球的重量。
感觉这题真是无聊。。。签到题还整这么麻烦,记录一下h1和h2,再一个for完事。
B:按照题目所给的图那样摆,问最少需要多少根木棒可以(通过补充)摆成n个正方形。
明显是直接一横一竖沿上方和左方摆。。。自己推一下公式,这道题的解法非常多。。。
C:真tm的坑,给你一个包含小写字母和* ?的字符串,保证* ?前面有字符。*可以删除前面的字符或者保留前面的字符,或者把前一个字符复制任意次。?只能删除前面的字符或者保留前面的字符。问你每个* ?选择使用方式以后,是否能使字符串长度为n。
坑点已经红色标注了,如果只复制一次会!挂!终!测!(说多了都是泪)
统计一下 * 和 ?的数量,然后按题意进行填充或删除即可。注意细节。
D:给你n-1个数a[i](2<=i<=n),表示i的祖先是a[i](无向边,保证构成树,1为根节点),然后给你n个数s[i]。
每个节点有权值,但是未知。
若i为奇数层节点,则s[i]为从根节点(1号节点)到i号节点的所有点的权值之和(包括第i个点),否则s[i]为-1。
现在请你给每个点赋权值,使所有节点的权值之和最小。如果不存在合法方案,输出-1。
思路:
其实树给了我们以后,只需一个dfs就很容易确定奇数层和偶数层的节点。
要使总权值最小,肯定是让分支节点承担尽可能大的值。
于是用一个dp数组,
dp[i]= s[i] i为奇数层节点
min(dp[i],dp[v]) i为偶数层节点,v为i节点的直接子节点
然后再dfs一下,val表示根节点到当前节点的权值和,对于奇数层的点,如果s[i]<val,那显然是-1了,否则令a[i]=val-s[i]。
对于偶数层的节点,如果dp[i]<val,显然还是-1,否则如果dp[i]未赋值(偶数层的叶子结点)。则a[i]=0即可,否则a[i]=dp[i]-val(想想是不是)。注意long long。
代码:
#include<bits/stdc++.h>
#define ll long long
#define inf 0x3f3f3f3f3f3f3f3fLL
using namespace std;
const int maxn=200010;
int n,m,k,x,y;
ll a[maxn],s[maxn];
ll c[maxn],dp[maxn];
ll ans,ct,cnt,tmp,flag;
vector<int>vc[maxn];
void dfs(int u,int fa,int dep)
{
c[u]=dep;
if(dep&1) dp[u]=s[u];
//if(dep&1) dp[u]=max(dp[u],s[u]);
for(int i=0;i<vc[u].size();i++)
{
int v=vc[u][i];
if(v==fa) continue;
dfs(v,u,dep+1);
if(dep%2==0)
{
dp[u]=min(dp[u],dp[v]);
}
}
/*if(vc[u].size()==1)
{
if(dep%2==0) dp[u]=0;
}*/
}
void dfs2(int u,int fa,int dep,ll val)
{
//cout<<val<<" "<<u<<" "<<s[u]<<endl;
//if((dep%2==0)&&vc[u].size()==1) return;
//else if(u!=1&&(dep&1)&&vc[u].size()==1) {ans+=val;return;}
if(dep&1)
{
if(val>s[u]) {flag=0;return;}
else a[u]=s[u]-val;
}
else
{
if(dp[u]<val) {flag=0;return;}
if(dp[u]==inf) a[u]=0;
else a[u]=dp[u]-val;
}
ans+=a[u];
//if(dep&1) dp[u]=max(dp[u],s[u]);
for(int i=0;i<vc[u].size();i++)
{
int v=vc[u][i];
if(v==fa) continue;
dfs2(v,u,dep+1,val+a[u]);
}
}
int main()
{
int T,cas=1;
scanf("%d",&n);
flag=1;ans=0;
for(int i=2;i<=n;i++)
{
scanf("%d",&m);
vc[i].push_back(m);
vc[m].push_back(i);
}
for(int i=1;i<=n;i++)
{
scanf("%lld",&s[i]);
dp[i]=inf;
}
memset(c,0,sizeof(c));
memset(a,0,sizeof(a));
//memset(dp,0,sizeof(dp));
dfs(1,-1,1);
//for(int i=1;i<=n;i++)
//cout<<dp[i]<<" "<<endl;
dfs2(1,-1,1,0);
if(!flag) puts("-1");
else printf("%lld\n",ans);
// if(flag) puts("Yes"); else puts("No");
return 0;
}