題意:在乙個學校裡,有n個人,他們之間的關係可以描述成一顆樹,樹上的父節點是其子節點的直屬上司。現在學校要舉辦乙個聚會,每個人來參加聚會,會產生a[i]的貢獻,但是如果乙個人的直系上司來參加聚會,那麼這個人無論如何都不會來參加。問你能夠產生的最大貢獻是多少?
思路:我們先找到入度為0的根節點,由根節點向下dfs,用f[i
][0/
1]
f[i][0/1]
f[i][0
/1]表示第i個人 不來/來 的時候,他的子樹能夠產生的最大貢獻。那麼狀態轉移就有兩種:
f [x
][1]
+=ma
x(0,
f[x]
[0])
f[x][1]+=max(0,f[x][0])
f[x][1
]+=m
ax(0
,f[x
][0])f[
x][0
]+=m
ax(0
,max
(f[x
][0]
,f[x
][1]
))
f[x][0]+=max(0,max(f[x][0],f[x][1]))
f[x][0
]+=m
ax(0
,max
(f[x
][0]
,f[x
][1]
))最後我們輸出max
(f[r
oot]
[0],
f[ro
ot][
1]
)max(f[root][0],f[root][1])
max(f[
root
][0]
,f[r
oot]
[1])
就行了。
**
#include
#define endl '\n'
#define null null
#define ls p<<1
#define rs p<<1|1
#define fi first
#define se second
#define mp make_pair
#define pb push_back
#define ll long long
//#define int long long
#define lowbit(x) x&-x
#define pii pair
#define ull unsigned long long
#define pdd pair
#define sz(x) (int)(x).size()
#define all(x) (x).begin(),(x).end()
#define mem(a,b) memset(a,b,sizeof(a))
#define ios ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
char
*fs,
*ft,buf[
1<<20]
;#define gc() (fs==ft&&(ft=(fs=buf)+fread(buf,1,1<<20,stdin),fs==ft))?0:*fs++;
inline
intread()
while
(ch>=
'0'&&ch<=
'9')
return x*f;
}using
namespace std;
const
int n=
6e3+
666;
const
int inf=
0x3f3f3f3f
;const
int mod=
1e9+7;
const
double eps=
1e-7
;const
double pi=
acos(-
1);int a[n]
,in[n]
,dp[n][2
];vector<
int>e[n]
;void
dfs(
int x)
}int
solve()
int root;
for(
int i=
1;i<=n;i++)if
(in[i]==0
) root=i;
dfs(root)
; cout<<
max(dp[root][0
],dp[root][1
])<}signed
main()
P1352 沒有上司的舞會
原題鏈結 樹形dp入門 dp方程搞錯了居然還過了90 利用dfs遞迴求解 每個點分為選和不選兩種情況 假設選為1不選為0 dp x 0 max dp num i 1 dp num i 0 這裡一開始寫成了dp num i 1 但它的兒子的兩種狀態實際上都是可選的 dp x 1 dp num i 0 ...
P1352 沒有上司的舞會
題目描述 某大學有n個職員,編號為1 n。他們之間有從屬關係,也就是說他們的關係就像一棵以校長為根的樹,父結點就是子結點的直接上司。現在有個周年慶宴會,宴會每邀請來乙個職員都會增加一定的快樂指數ri,但是呢,如果某個職員的上司來參加舞會了,那麼這個職員就無論如何也不肯來參加舞會了。所以,請你程式設計...
P1352 沒有上司的舞會
題目 p1352 沒有上司的舞會 演算法標籤 dp,搜尋,樹形結構,記憶化搜尋 從樹的頭往下求結果會有後效性,且有多個葉子節點,資料不易處理 則採用,葉子節點往頭部求結果 對於某一節點,有選擇和不選擇兩種情況 1 不選擇的話 記 dp 0 for int i 0 i a x tail.size i ...