A. Promises I Can't Keep
题目意为求以每个点为根时的期望得分的最大值,换根DP即可。
式子不太难推,半个小时就出来了。太长了不往这写了。
Code
#include<bits/stdc++.h>
#define ll long long
#define il inline
#define read(x){\
char ch;\
int fu=1;\
while(!isdigit(ch=getchar()))\
fu-=(ch=='-')<<1;\
x=ch&15;\
while(isdigit(ch=getchar()))\
x=(x<<1)+(x<<3)+(ch&15);\
x*=fu;\
}
#define pb push_back
using namespace std;
namespace asbt{
namespace cplx{bool begin;}
const int maxn=5e5+5;
int n,cnt[maxn];
double a[maxn],f[maxn];
vector<int> e[maxn];
il void dfs1(int u,int fa){
f[u]=a[u];
for(int v:e[u]){
if(v==fa){
continue;
}
dfs1(v,u);
cnt[u]++;
}
for(int v:e[u]){
if(v==fa){
continue;
}
f[u]+=f[v]/cnt[u];
}
}
il void dfs2(int u,int fa){
for(int v:e[u]){
if(v==fa){
continue;
}
double tmp=cnt[u]==1?a[u]:(((f[u]-a[u])*cnt[u]-f[v])/(cnt[u]-1)+a[u]);
f[v]=a[v]+((f[v]-a[v])*cnt[v]+tmp)/(cnt[v]+1);
cnt[v]++;
dfs2(v,u);
}
}
namespace cplx{
bool end;
il double usdmem(){return (&begin-&end)/1048576.0;}
}
int main(){
read(n);
for(int i=1,u,v;i<n;i++){
read(u)read(v);
e[u].pb(v),e[v].pb(u);
}
for(int i=1;i<=n;i++){
scanf("%lf",a+i);
}
dfs1(1,0),dfs2(1,0);
double ans=0;
for(int i=1;i<=n;i++){
ans=max(ans,f[i]);
}
// for(int i=1;i<=n;i++){
// cout<<f[i]<<" ";
// }
// puts("");
printf("%.4f",ans);
return 0;
}
}
int main(){return asbt::main();}
/*
4
1 2
2 3
2 4
1 2 3 4
*/
刚这个是考场代码,直接0分。
原因是:
接下来电流会等概率且不重复经过一个点地流向一个叶子节点
一个叶子节点,不是一个子节点。。。
正解在这里
Code
#include<bits/stdc++.h>
#define ll long long
#define il inline
#define read(x){\
char ch;\
int fu=1;\
while(!isdigit(ch=getchar()))\
fu-=(ch=='-')<<1;\
x=ch&15;\
while(isdigit(ch=getchar()))\
x=(x<<1)+(x<<3)+(ch&15);\
x*=fu;\
}
#define pb push_back
using namespace std;
namespace asbt{
namespace cplx{bool begin;}
const int maxn=5e5+5;
int n,a[maxn],cnt[maxn],tot;
long double f[maxn];
vector<int> e[maxn];
il void dfs1(int u,int fa){
f[u]=a[u];
if(fa&&e[u].size()==1){
cnt[u]=1;
}
for(int v:e[u]){
if(v==fa){
continue;
}
dfs1(v,u);
cnt[u]+=cnt[v];
}
for(int v:e[u]){
if(v==fa){
continue;
}
f[u]+=f[v]*cnt[v]/cnt[u];
}
}
il void dfs2(int u,int fa){
for(int v:e[u]){
if(v==fa){
continue;
}
double tmp=(((f[u]-a[u])*cnt[u]-f[v]*cnt[v]))/(tot-cnt[v])+a[u];
tmp=(f[v]-a[v])*cnt[v]+tmp*(tot-cnt[v]);
cnt[v]=tot;
if(e[v].size()==1){
cnt[v]--;
}
f[v]=tmp/cnt[v]+a[v];
dfs2(v,u);
}
}
namespace cplx{
bool end;
il double usdmem(){return (&begin-&end)/1048576.0;}
}
int main(){
read(n);
for(int i=1,u,v;i<n;i++){
read(u)read(v);
e[u].pb(v),e[v].pb(u);
}
for(int i=1;i<=n;i++){
read(a[i]);
if(e[i].size()==1){
tot++;
}
}
dfs1(1,0);
// for(int i=1;i<=n;i++){
// cout<<cnt[i]<<" ";
// }
// puts("");
dfs2(1,0);
// for(int i=1;i<=n;i++){
// cout<<f[i]<<" ";
// }
// puts("");
long double ans=-1e18;
for(int i=1;i<=n;i++){
ans=max(ans,f[i]);
}
printf("%.4Lf",ans);
return 0;
}
}
int main(){return asbt::main();}
/*
5
1 2
2 3
3 4
4 5
1 2 3 4 5
*/
B. [COCI2016-2017#4] Rima
考场上想到了倒着建trie,也想到了父亲和儿子只有两种情况,但是忽略了一个很重要的性质,那就是因为没有两个相同的字符串,所以最后形成的字符串序列一定是一个长度先减后增的样子。
所以可以在trie树上搞一个很简单的DP,设 \(dp[u]\) 表示以 \(u\) 为结尾的字符串在一端的最长序列,于是当 \(u\) 是一个结尾,且它的儿子也是一个结尾时,就可以转移。
最终的答案一定是先减后增的情况,式子也不难推。
Code
#include<bits/stdc++.h>
#define ll long long
#define il inline
#define read(x){\
char ch;\
int fu=1;\
while(!isdigit(ch=getchar()))\
fu-=(ch=='-')<<1;\
x=ch&15;\
while(isdigit(ch=getchar()))\
x=(x<<1)+(x<<3)+(ch&15);\
x*=fu;\
}
#define pb push_back
#define mp make_pair
#define fir first
#define sec second
using namespace std;
namespace asbt{
namespace cplx{bool begin;}
const int maxn=3e6+5;
int n,tot,dp[maxn],end[maxn];
vector<pair<int,char> > e[maxn];
char s[maxn];
namespace cplx{
bool end;
il double usdmem(){return (&begin-&end)/1048576.0;}
}
int main(){
read(n);
for(int i=1;i<=n;i++){
scanf(" %s",s+1);
int len=strlen(s+1);
int p=0;
for(int j=len;j;j--){
for(auto x:e[p]){
if(x.sec==s[j]){
p=x.fir;
goto togo;
}
}
e[p].pb(mp(++tot,s[j]));
p=tot;
togo:;
}
end[p]++;
}
int ans=0;
for(int u=tot;~u;u--){
int mx1=0,mx2=0,cnt=0;
for(auto x:e[u]){
int v=x.fir;
cnt+=end[v];
if(dp[v]>mx1){
mx2=mx1;
mx1=dp[v];
}
else{
mx2=max(mx2,dp[v]);
}
}
if(end[u]){
dp[u]=mx1+max(cnt,1);
}
ans=max(ans,mx1+mx2+max(cnt-2,0)+end[u]);
}
printf("%d",ans);
return 0;
}
}
int main(){return asbt::main();}
C. [CEOI2020] 星际迷航
之前就出过一次这道题,当时改过了,但是那道题数据太水了,所以同一篇代码拿到这里直接获得7pts……
先咕着吧
D. 「SMOI-R1」Company
标签:专项,ch,int,cnt,fa,树形,il,dp,define From: https://www.cnblogs.com/zhangxyhp/p/18608284