poj-1463 Strategic game(樹狀DP入門)
阿新 • • 發佈:2018-11-10
https://vjudge.net/problem/POJ-1463
題意:一棵樹,放哨兵站崗,如果有一個點放置了兵,那麼與其相連的所有點都能被監視,求樹的所有點都被監視且放置哨兵數目最少。
思路:dp[maxn][2]
dp[i][0]表示不選取該點,dp[i][1]表示選取該點。
若該點不選取,則其子節點必須都被選取。
若該點選取,則應選取min(dp[son][0],dp[son][1]);
類似的題目:https://blog.csdn.net/qq_38924883/article/details/82988994
#include<iostream> #include<cstdio> #include<vector> #include<cstring> #define maxn 1505 using namespace std; int dp[maxn][2],degree[maxn],vis[maxn]; vector<int>v[maxn]; void dfs(int u) { vis[u]=1; for(int i=0;i<v[u].size();i++) { if(vis[v[u][i]]) continue; dfs(v[u][i]); dp[u][0]+=dp[v[u][i]][1]; dp[u][1]+=min(dp[v[u][i]][0],dp[v[u][i]][1]); } } int main() { ///ios::sync_with_stdio(false); int n; while(cin>>n) { memset(degree,0,sizeof(degree)); memset(vis,0,sizeof(vis)); for(int i=0;i<maxn;i++) v[i].clear(); int u,to,m; for(int i=0;i<n;i++) { dp[i][0]=0;dp[i][1]=1; scanf("%d:(%d)",&u,&m); for(int i=0;i<m;i++) { scanf("%d",&to); v[u].push_back(to); degree[to]++; } } int root; for(int i=0;i<n;i++) { if(degree[i]==0) { root=i; break; } } dfs(root); cout<<min(dp[root][0],dp[root][1])<<endl; } return 0; }