bzoj4013 HNOI2015 實驗比較

2022-08-22 21:51:11 字數 1417 閱讀 7108

傳送門:

思路:首先把等於的縮成乙個點,由好的向壞的連邊,有環肯定無解。

然後題目裡說「小

d都最多隻記住了某一張質量不比

i差的另一張

ki」那就是每個點就最多只有一條入邊,那存在合法方案的圖就一定是森林。

加乙個虛根,這可以樹形dp了。

假設f[i][j]表示i號點的子樹中的所有點構成的有且只有j個小於號的序列的個數

那麼考慮怎麼合併兩個子樹的答案

假設現在的兩個兒子是x,y,子樹大小分別為siz[x],siz[y]

列舉兩個兒子的序列小於號個數i,j。

那麼合併出來的新序列小於號個數k就在max(i,j)到i+j之間。

那麼問題就是求對於k個盒子,有i個白球,j個黑球,求有多少種方案。

答案就是f[x][i]*f[y][j]*c[k][i]*c[i][j-(k-i)]    c是組合數。

實現的時候,再開乙個g陣列,g[i]

就是之前的兒子的子樹的點構成的小於號為j個的序列方案數

注意兒子合併完後,因為新加了當前點,序列長度要+1

#include#include#include#includeconst int maxn=105,maxm=205,mod=(int)(1e9+7);

typedef long long ll;

using namespace std;

int n,m,pre[maxm],now[maxn],son[maxm],tot,fa[maxn],cnt,deg[maxn],siz[maxn];char op[3];

ll c[maxn][maxn],f[maxn][maxn],ans,g[maxn];

bool bo[maxn];

struct nodeli[maxn];

void add(int a,int b)

int getfa(int x)

bool dfs(int x,int fa)

else

} if (x)

return 1;

}int main()

if (op[0]=='>') swap(x,y);

li[++cnt]=(node);

} for (int i=1;i<=cnt;i++)

for (int i=1;i<=n;i++) if (!deg[getfa(i)]) add(0,getfa(i));

if (!dfs(0,-1)) return puts("0"),0;

//for (int i=1;i<=n;i++) printf("%d %lld\n",i,f[0][i]);

for (int i=1;i<=siz[0];i++) ans=(ans+f[0][i])%mod;

printf("%lld\n",ans);

return 0;

}

BZOJ4013 HNOI2015 實驗比較

先並查集合並 因為所有的xi互不相同,所以合併完後應該是乙個森林,如果出現環就無解。我們新建乙個根連向所有入度為0的點,就變成了一棵樹,考慮樹形dp。因為只要兩點不是其中一點是另一點的祖先的關係,他們就可以劃 因為大小關係不確定,所以將 連線的看做一塊,f i j 表示以 i 為根的子樹分成了j塊 ...

BZOJ 4013 HNOI2015 實驗比較

樹dp 組合數 網上題解很多,這裡就放個有注釋的 code 1 include 2 include 3 include 4 include 5 include 6 include 7 define maxn 110 8 define mod 1000000007 9using namespace s...

4013 HNOI2015 實驗比較

time limit 5 sec memory limit 512 mb submit 535 solved 268 submit status discuss 小d n 張,編號為1 到 n。實驗分若干輪進行,在每輪實驗中,小 d會被要求 某兩張隨機選取的,然後小d 需要根據他自己主觀上的判斷確定...