Codeforces Round #627 (Div. 3) E&F

E

题解:
线性dp, f ( i , j ) f(i,j) f(i,j)表示处理到第i个任务且在第j时间睡觉的最大好的答案总数。

#include 
using namespace std;
int dp[2005][2005], a[2005];
int main(){
    int n, h, l, r;
    cin >> n >> h >> l >> r;
    memset(dp,-0x3f3f3f3f,sizeof(dp));
    dp[0][0] = 0;
    for(int i = 1; i <= n; i++){
        cin >> a[i];
    }
    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]);
            }
            if((j + a[i] - 1) % h >= l && (j + a[i] - 1) % h <= r){
                dp[i][(j+a[i]-1)%h] = max(dp[i][(j+a[i]-1)%h], dp[i-1][j] + 1);
            }
            else{
                dp[i][(j+a[i]-1)%h] = max(dp[i][(j+a[i]-1)%h], dp[i-1][j]);
            }
        }
    }
    cout<<*max_element(dp[n],dp[n]+h)<<endl;
    return 0;
}

F

题解:
树的换根。

#include 
using namespace std;
const int N=2e5+7;
int a[N],cnt,head[N],e[N*2],ne[N*2],sz[N],res[N];
void add(int a,int b)
{
    e[cnt]=b,ne[cnt]=head[a],head[a]=cnt++;
}
void dfs(int u,int f)
{
    int sum=0;
    sz[u]=a[u];
    for(int i=head[u];~i;i=ne[i]){
        int j=e[i];
        if(j==f) continue;
        dfs(j,u);
        sum+=max(0,sz[j]);
    }
    sz[u]+=sum;
}
void dfs1(int u,int f)
{
    res[u]=sz[u];
    for(int i=head[u];~i;i=ne[i]){
        int j=e[i];
        if(j==f) continue;
        sz[u]-=max(sz[j],0);
        sz[j]+=max(0,sz[u]);
        dfs1(j,u);
        sz[j]-=max(sz[u],0);
        sz[u]+=max(sz[j],0);
    }
}
int main()
{
    memset(head,-1,sizeof head);
    int n; 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 a,b; scanf("%d%d",&a,&b);
        add(a,b); add(b,a);
    }
    dfs(1,-1);
    dfs1(1,-1);
    for(int i=1;i<=n;i++) printf("%d ",res[i]);
    puts("");
}

你可能感兴趣的:(codeforces)