[USACO 2017DEC] Barn Painting

[题目链接]

https://www.lydsy.com/JudgeOnline/problem.php?id=5141

[算法]

树形DP

时间复杂度 : O(N)

[代码]

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int MAXN = 1e5 + 10;
const int MAXC = 5;
const int P = 1e9 + 7;

struct edge
{
    int to , nxt;
} e[MAXN << 1];

int n , k , tot;
int color[MAXN] , head[MAXN];
LL f[MAXN][MAXC];

template <typename T> inline void chkmax(T &x,T y) { x = max(x , y); }
template <typename T> inline void chkmin(T &x,T y) { x = min(x , y); }
template <typename T> inline void read(T &x)
{
    T f = 1; x = 0;
    char c = getchar();
    for (; !isdigit(c); c = getchar()) if (c == ‘-‘) f = -f;
    for (; isdigit(c); c = getchar()) x = (x << 3) + (x << 1) + c - ‘0‘;
    x *= f;
}
template <typename T> inline void update(T &x,T y)
{
    x += y;
    x %= P;
}
template <typename T> inline void mul(T &x,T y)
{
    x = x * y;
    x %= P;
}

inline void addedge(int u,int v)
{
    tot++;
    e[tot] = (edge){v , head[u]};
    head[u] = tot;
}
inline LL dp(int u , int k , int fa)
{
    if (f[u][k] != -1) return f[u][k];
    f[u][k] = 1;
    for (int i = head[u]; i; i = e[i].nxt)
    {
        int v = e[i].to;
        if (v == fa) continue;
        if (color[v])
        {
            if (color[v] == k)
                return f[u][k] = 0;
            else mul(f[u][k] , dp(v , color[v] , u));
        } else
        {
            LL value = 0;
            for (int j = 1; j <= 3; j++)
                if (j != k)
                    update(value , dp(v , j , u));
            mul(f[u][k] , value);
        }
    }
    return f[u][k];
}

int main()
{

    read(n); read(k);
    for (int i = 1; i < n; i++)
    {
        int x , y;
        read(x); read(y);
        addedge(x , y);
        addedge(y , x);
    }
    for (int i = 1; i <= k; i++)
    {
        int b , c;
        read(b); read(c);
        color[b] = c;
    }
    for (int i = 1; i <= n; i++) f[i][1] = f[i][2] = f[i][3] = -1;
    if (color[1])
    {
        printf("%lld\n",dp(1 , color[1] , -1));
    } else
    {
        LL ans = 0;
        for (int i = 1; i <= 3; i++) update(ans , dp(1 , i , -1));
        printf("%lld\n",ans);
    }

    return 0;
}

原文地址:https://www.cnblogs.com/evenbao/p/9800139.html

时间: 2024-10-01 05:22:21

[USACO 2017DEC] Barn Painting的相关文章

[USACO17DEC] Barn Painting

题目描述 Farmer John has a large farm with NN barns (1 \le N \le 10^51≤N≤105 ), some of which are already painted and some not yet painted. Farmer John wants to paint these remaining barns so that all the barns are painted, but he only has three paint co

usaco Big Barn

比较简单的动态规划啦,以前学动规时讲过,还知道另外一种方法,如果是求最大的矩形的话就只能用另外一中了,代码长些. /* ID: modengd1 PROG: bigbrn LANG: C++ */ #include <iostream> #include <stdio.h> #include <memory.h> using namespace std; int input[1001][1001]; int N,T; int main() { freopen("

Luogu4084 [USACO17DEC]Barn Painting (树形DP)

数组越界那个RE+WA的姹紫嫣红的... 乘法原理求种类数,类似于没有上司的舞会. #include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <cmath> #define R(a,b,c) for(register int a = (b); a <= (c); ++ a) #define nR(a,b,c) for(regi

USACO Section 5.3 Big Barn(dp)

USACO前面好像有类似的题目..dp(i,j)=min(dp(i+1,j),dp(i+1,j+1),dp(i,j+1))+1  (坐标(i,j)处无tree;有tree自然dp(i,j)=0) .dp(i,j)表示以坐标(i,j)为左上角的barn边长最大值,dp(i+1,j),dp(i,j+1)分别表示向右和向下能扩展的最大边长,但是以此为正方形时,右下方的一个格子没有考虑到,所以就+个dp(i+1,j+1).边界为:dp(i,j)=1(i==n-1或j==n-1). -----------

USACO 1.3 Barn Repair

Barn Repair It was a dark and stormy night that ripped the roof and gates off the stalls that hold Farmer John's cows. Happily, many of the cows were on vacation, so the barn was not completely full. The cows spend the night in stalls that are arrang

[USACO 12DEC]Running Away From the Barn

Description It's milking time at Farmer John's farm, but the cows have all run away! Farmer John needs to round them all up, and needs your help in the search. FJ's farm is a series of N (1 <= N <= 200,000) pastures numbered 1...N connected by N - 1

Usaco 1.3.2 修理牛棚(Barn Repair)

  Barn Repair 题意:在一个夜黑风高,下着暴风雨的夜晚,农民约翰的牛棚的屋顶.门被吹飞了. 好在许多牛正在度假,所以牛棚没有住满. 剩下的牛一个紧挨着另一个被排成一行来过夜. 有些牛棚里有牛,有些没有. 所有的牛棚有相同的宽度. 自门遗失以后,农民约翰必须尽快在牛棚之前竖立起新的木板. 他的新木材供应商将会供应他任何他想要的长度,但是供应商只能提供有限数目的木板. 农民约翰想将他购买的木板总长度减到最少. 给出:可能买到的木板最大的数目M(1<= M<=50);牛棚的总数S(1&l

USACO 1.3 Barn Repair(贪心)

这道题同样也是贪心 要使木板总长度最少,就要使未盖木板的长度最大. 我们先用一块木板盖住牛棚,然后,每次从盖住的范围内选一个最大的空隙,以空隙为界将木板分成两块,重复直到分成m块或没有空隙. /* ID:twd30651 PROG:barn1 LANG:C++ */ #include<iostream> #include<fstream> #include<stdlib.h> //#define DEBUG using namespace std; int M; int

【USACO 1.3】Barn Repair

贪心,去掉最大的min(m,c)-1个间隔 /******************************************* TASK: barn1 LANG: C++ Created Time: 2016/9/9 14:36:17 *********************************/ #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> u