1466D - 13th Labour of Heracles
一看以为这是树的题目,但其实是比较水的,观察一下可以发现加了另外一个颜色后非叶子节点会多加一遍,所以我们优先让权值大的多加一遍,这个点的权值可以加的次数是这个点的度数-1,这题就做完了,统计度数之后从大到小依次加就行
double eps=1e-8;
ll t,n,in[200005];
struct node{
ll id,val;
bool operator<(const node& a) const{
return val>a.val;
}
}w[200005];
int main(){
scanf("%lld",&t);
while(t--){
scanf("%lld",&n);
ll sum=0;
for(int i=1;i<=n;i++) scanf("%lld",&w[i].val),sum+=w[i].val,w[i].id=i;
for(int i=1;i<n;i++){
ll u,v;
scanf("%lld%lld",&u,&v);
in[u]++;in[v]++;
}
sort(w+1,w+n+1);
printf("%lld ",sum);
for(int i=1;i<=n;i++){
while(in[w[i].id]>1){
sum+=w[i].val;
printf("%lld ",sum);
in[w[i].id]--;
}
}
printf("\n");
for(int i=1;i<=n;i++) in[i]=0;
}
system("pause");
return 0;
}
P6140 [USACO07NOV]Best Cow Line S - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
这题的数据较弱直接暴力就能过,首尾比较每次都先放小的,如果相等的话就去前面比较,一直比到不相等为止,然后在判断哪个小就放哪个,如果都相等就随便放
ll n,m;
char s[500005];
bool cmp(ll l,ll r){
while(s[l]==s[r]&&l<r) l++,r--;
if(l<r) return s[l]<s[r];
else return 1;
}
int main(){
scanf("%lld",&n);
for(int i=1;i<=n;i++) cin>>s[i];
ll l=1,r=n,cnt=0;
while(l<=r){
if(s[l]<s[r]){cout<<s[l];l++;cnt++;}
else if(s[l]>s[r]){cout<<s[r];r--;cnt++;}
else{
if(cmp(l,r)){cout<<s[l];l++;cnt++;}
else{cout<<s[r];r--;cnt++;}
}
if(cnt>=80){printf("\n");cnt=0;}
}
system("pause");
return 0;
}
1519D - Maximum Sum of Products 区间dp
感觉之前做过类似的,然后就疯狂的想试一试之前的结论管不管用,然后试了半天也不对,最后看题解是区间dp,,,dp[i][j]表示i到j这块区间反转,c[i]表示前缀和,转移也很好转移,dp[i][j]=dp[i+1][j-1]+a[j]*b[i]+a[i]*b[j],就是由小区间转移到大区间,枚举长度和起点就可以了
D. Maximum Sum of Products(前缀和 + 区间dp)_青山_12的博客-CSDN博客
int mod=1e9+7;
double eps=1e-8;
ll n,a[5005],b[5005],c[5005],dp[5005][5005];
int main(){
scanf("%lld",&n);
for(int i=1;i<=n;i++) scanf("%lld",&a[i]);
for(int i=1;i<=n;i++) scanf("%lld",&b[i]),c[i]=c[i-1]+a[i]*b[i],dp[i][i]=a[i]*b[i];
ll ans=c[n];
for(int len=1;len<n;len++)
for(int i=1;i+len<=n;i++){
ll j=i+len;
dp[i][j]=dp[i+1][j-1]+a[j]*b[i]+a[i]*b[j];
ll sum=dp[i][j]-(c[j]-c[i-1])+c[n];
ans=max(ans,sum);
}
printf("%lld\n",ans);
system("pause");
return 0;
}
B-Gaming_牛客小白月赛54 (nowcoder.com) 差分
淦,从出发点就想错了,想成了区间覆盖,丫的根本就不是,因为他只需要不要一个debuff就可以了,就可以去枚举不要那个损失最少,把区间的s[i]都加到每个点上,然后总和减去最小的点就可以
int mod=1e7+7;
double eps=1e-8;
ll n,m,b[1000006];
int main(){
scanf("%lld%lld",&n,&m);
ll minn=1e18,ans=0;
for(int i=1;i<=n;i++){
ll x,y,z;
scanf("%lld%lld%lld",&x,&y,&z);
b[x]+=z;b[y+1]-=z;
ans+=z;
}
for(int i=1;i<=m;i++) b[i]+=b[i-1];
for(int i=1;i<=m;i++) minn=min(minn,b[i]);
printf("%lld\n",ans-minn);
system("pause");
return 0;
}