anniversary party 題目鏈結
裡面的關係是乙個樹狀的無環圖,每個節點我們顯然有兩種取法,參加派對,不參加派對,所以狀態轉移方程就出來了
#includeusing namespace std;
const int n = 1e4 + 10;
int head[n], to[n], nex[n], in[n], cnt = 1;
int dp[n][2], n;
void add(int x, int y)
void dfs(int rt, int fa)
}}int main()
int x, y;
while(scanf("%d %d", &x, &y) && (x + y))
add(y, x);
for(int i = 1; i <= n; i++)
if(!in[i])
}return 0;
}
p2996 [usaco10nov]visiting cows g
入門題都懂了,這題想必大佬們肯定能寫。
#includeusing namespace std;
const int n = 1e5 + 10;
int head[n], to[n], nex[n], cnt = 1;
int dp[n][2], n;
void add(int x, int y)
void dfs(int rt, int fa)
}}int main()
dp[n][1] = 1;
dfs(1, 0);
printf("%d\n", max(dp[1][0], dp[1][1]));
return 0;
}
rebuilding roads 題目鏈結
思路不難,dp[i][j]陣列,記錄的時第i個節點加上其子樹上與其相連的節點的數量時j時,需要切斷的路徑顯然有dp[i][1] = 與其直接相連的子樹加上乙個父節點的路徑。
然後狀態轉移方程就有了 \(dp[i][j] = min(dp[i][j], dp[i][k] + dp[i_][j - k] - 2)\),這個減二的操作是因為,這兩個之間相連的邊都在互相的dp陣列中記錄了,所以需要減去2。
接下來就要說乙個細節了,我們在最後的答案中dp[root]中所有的都要減去1,因為在之前我們把其父節點的邊加進去了,但是他是沒有父節點的。這個點,坑人啊,還是太菜了。
// #include#include#include#include#includeusing namespace std;
const int n = 2e2 + 10;
int head[n], to[n], nex[n], in[n], cnt;
int dp[n][n], sz[n], n, m;
void add(int x, int y)
void dfs1(int rt, int fa)
}}void solve(int rt, int fa)
}}int main()
for(int i = 1; i <= n; i++)
if(in[i] == 0)
for(int i = 1; i <= n; i++)//好像可以直接在dfs1中完成,,,,
dp[i][1] = sz[i];
// cout << sz[i] << endl;
for(int i = 1; i <= n; i++)
if(in[i] == 0)
// for(int i = 1; i <= n; i++)//除錯bug_ing
// for(int j = 1; j <= m; j++)
int ans = 0x3f3f3f3f;
for(int i = 1; i <= n; i++)
dp[i][m] < ans ? ans = dp[i][m] : ans = ans;//終於出答案了,寫了一長串我現在看不懂的表示式,,,,
printf("%d\n", ans);
}return 0;
}
其實也挺好理解的。
最優連通子集 題目鏈結
這是一道要自己建圖的題,顯然我們不難想到,在dis = 1的兩個點之間建立聯通的邊,接下來的事情就是樹上dp了。
考慮狀態轉移方程,對於每乙個點我們可以將其放入聯通集或者不放入聯通集,同時我們還要保證,每乙個點對都是互相連通的。
我們用dp[i][0]表示這個點不在聯通集上,用dp[i][1]表示這個點在聯通集上。
考慮dp[i][0]如何變化,不難發現他的值一定是其子樹上的最大值,所以 \(dp[i][0] = max(dp[i][0], dp[i_][1], dp[i_][0])\)
接著我們考慮dp[i][1],我們要保證它的連通性,得到 \(dp[i][1] = max(dp[i][1], dp[i_][1] + dp[i][1])\)
然後按照這個思路跑一遍dfs就行了。
// #include#include#include#include#includeusing namespace std;
const int n1 = 1e3 + 10, n2 = 1e6 + 10;
int head[n1], to[n2], nex[n2], cnt;
int dp[n1][2], n;
struct point a[n1];
void add(int x, int y)
void dfs(int rt, int fa)
}}int main()
for(int i = 1; i <= n; i++)
for(int j = i + 1; j <= n; j++)
if((abs(a[i].x - a[j].x) + abs(a[i].y - a[j].y)) == 1)
dfs(1, 0);
// for(int i = 1; i <= n; i++)
// printf("%d %d\n", dp[i][0], dp[i][1]);
printf("%d\n", max(dp[1][0], dp[1][1]));
}return 0;
}
本來應該還有第四道題,沒想到考察了樹上揹包,但是這個東西我還沒學過啊,就先咕咕咕咕咕下了。 樹型DP入門
題意 某公司要舉辦一次晚會,但是為了使得晚會的氣氛更加活躍,每個參加晚會的人都不希望在晚會中見到他的直接上司,現在已知每個人的活躍指數和上司關係 當然不可能存在環 求邀請哪些人 多少人 來能使得晚會的總活躍指數最大。思路 任何乙個點的取捨可以看作一種決策,那麼狀態就是在某個點取的時候或者不取的時候,...
樹型DP 選課
大學裡實行學分。每門課程都有一定的學分,學生只要選修了這門課並考核通過就能獲得相應的學分。學生最後的學分是他選修的各門課的學分的總和。每個學生都要選擇規定數量的課程。其中有些課程可以直接選修,有些課程需要一定的基礎知識,必須在選了其它的一些課程的基礎上才能選修。例如,資料結構 必須在選修了 高階語言...
樹型DP 皇宮看守
太平王世子事件後,陸小鳳成了皇上特聘的御前一品侍衛。皇宮以午門為起點,直到後宮嬪妃們的寢宮,呈一棵樹的形狀 有邊直接相連的宮殿可以互相望見。大內保衛森嚴,三步一崗,五步一哨,每個宮殿都要有人全天候看守,在不同的宮殿安排看守所需的費用不同。可是陸小鳳手上的經費不足,無論如何也沒法在每個宮殿都安置留守侍...