有n個點(n<=40)標記為0,1,2,…n-1,每個點i有個價值val[i],如果val[i]=-1那麼這個點被定義為bad,否則如果val[i] >=0那麼這個點為定義為good。現在給這n個點間連上n-1條邊,使它們構成乙個生成樹,定義樹中的點為great點當且僅當這個點本身是good點且與其相鄰的點中至少有另乙個good點。樹的價值等於樹中所有great點的價值和。定義限制價值樹是指價值不大於maxval的樹,問對給定的val與maxval,一共有多少種不同的限制**樹?由於答案太大,可取
modulo 1,000,000,007後的結果。
說明:兩棵樹是不同的,指兩棵樹的邊集不同,注意這裡的邊都是無向邊。
其實我們可以發現,所有的good點和bad點其實都是一樣的,是沒有區別的
我們只需要對於他們,排列組合一下求方案就好了
如果我們知道,有f[
i]f [i
]表示剛好有i個點是great點
並且我們還知道乙個h[
i]h [i
]表示有多少種方案,使得選了i個good點,並且他們的值合法
那麼乘起來就可以了 h[
i]h [i
]的計算顯然可以用折半搜尋來完成 至於f
[i] f[i
]則需要容斥 考慮g
[i] g[i
]表示至少i個點不是great點,就是說著i個只可以和bad相連
那麼這個可以用矩陣樹定理來做。。
sb的我一開始不記得要用余子式,直接就用原來的行列式了
於是就可以容斥了 f[
i]=∑
totj
=i+1
f[j]
∗cj−
itot
−if [i
]=∑j
=i+1
totf
[j]∗
ctot
−ij−
i注意後面的組合數,這個我想了很久
一開始我以為可以直接減,發現錯了。。
因為剩下這j−
i j−i
的數,也是要排列組合看一看的
code:
#include
#include
#include
#include
#include
using namespace std;
typedef long long ll;
const ll mod=1e9+7;
const ll max=(1
<<30);
const ll n=45;
ll n,m;
ll tot,tot1;//有多少good點 有多少個bad點
ll val[n];
ll ooo;
pair a[1048580];
int cnt[1048580][21];//點i個方案,選了j個點的有多少個
ll h[n];//有多少種選法,使得選出來i個great點是合法的
void dfs (ll x,ll y,ll a,ll b)//現在選了多少個了,值是多少
dfs(x+1,y,a,b);
if (b+val[x]<=m) dfs(x+1,y,a+1,b+val[x]);
}void dfs2 (ll x,ll y,ll a,ll b)
dfs2(x+1,y,a,b);
if (b+val[x]<=m) dfs2(x+1,y,a+1,b+val[x]);
}ll g[n],f[n];//至少有i個不是great點 剛好有i個不是great點
ll c[n][n];//行列式
ll gauss (ll x)//前i個good點只能連bad點
*/ ll ans=1;//被翻轉了多少次
for (ll u=1;uif (c[u][u]==0)
for (ll u=1;ufor (ll i=u+1;iwhile (c[i][u]!=0)
ans=-ans;}}
for (ll u=1;u*c[u][u]%mod;
/* printf("ans:%lld\n",ans);
system("pause");*/
ans=(ans+mod)%mod;
return ans;
}ll jc[n],inv[n];
ll c (ll x,ll y)
ll pow (ll x,ll y)
void dp ()
}}int main()
sort(val+1,val+1+n);
dp();
/*for (int u=0;u<=tot;u++) printf("%lld ",f[u]);
printf("\n");
for (int u=0;u<=tot;u++) printf("%lld ",g[u]);
printf("\n");*/
dfs(1,tot/2,0,0);
sort(a+1,a+1+ooo);
for (ll u=1;u<=ooo;u++)
dfs2(tot/2+1,tot,0,0);
ll ans=0;
for (ll u=0;u<=tot;u++) ans=ans+f[u]*h[tot-u]%mod;
printf("%lld\n",ans%mod);
}return
0;}
51Nod1446 限制價值樹
講課時候一點兒都沒懂 分成兩個部分 找到所有滿足sum mx的集合,即列舉哪些是great的 統計每個great的集合對應多少個樹 發現,第二個部分只和great集合大小有關 具體的第乙個部分 折半爆搜 sort 雙指標,得到g i 大小為i的great集合個數 第二部分 f i 表示欽定i個是gr...
51nod 1446 價值限制樹
51nod 1446 價值限制樹 真 一調一下午。題意 給 n 個點,每個點有權值 a i 若 a i 1 稱這個點 not good 否則是 good 的。形成任意一棵生成樹後若 good 的點相鄰的點有 good 點,則稱該點是 great 的。生成樹的價值是所有 great 的點的權值和。給定...
51Nod 1296 有限制的排列
acm模版 個人感覺,這個應該算是數字 dp。先通過處理輸入資料獲取乙個 state,表示每相鄰兩項之間的大小關係,state i 0,表示無特別關係,state i 1 表示第 i 項小於第 i 1 項,state i 2 表示第 i 項大於第 i 1 項。接著搞乙個 dp i j 表示由前 i ...