gdfzoj 785 買水果(樹上dp)

2021-08-07 05:49:50 字數 1350 閱讀 9959

標籤:樹上dp

原題鏈結

(其實並沒有什麼用)

考慮到q比較龐大(10^5級別),我們不能用單個處理詢問的方法來解決,這道題的方法是用樹上dp來做。我們令f[i][j][0]表示在以i點為根,有j個黑點時白點的最大數量,同理,f[i][j][1]表示在以i點為根,有j個黑點時白點的最小數量。我們不難得到轉移方程:

f[x][i+j][0]=min(f[x][i][0]+f[o][j][0])

f[x][i+j][1]=max(f[x][i][1]+f[o][j][1])

注:x表示當前節點,o列舉x所有的兒子,用鄰接表實現。

有乙個細節問題,i,j都要倒序列舉,否則乙個兒子節點會被重複計算。

時間複雜度為o(n^3+n*q),詳見**。

#include

#include

#include

#define maxn 805

#define inf 1000000000

#define add(u,v) (to[++top]=head[u],head[u]=top,w[top]=v)

#define for(x) for(int h=head[x],o=w[h];h;o=w[h=to[h]])

using

namespace

std;

int n,i,j,q,x,y,to[maxn],head[maxn],w[maxn],f[maxn][maxn][2],top=0;

bool vis[maxn],c[maxn],ff;

inline

void dfs(int x) }

int main()

for (i=1;i<=n;i++) scanf("%d",&c[i]);

for (i=1;i<=n;i++)

for (j=0;j<=n;j++) f[i][j][0]=inf,f[i][j][1]=-1;

memset(vis,0,sizeof(vis));

dfs(1);

while (q--)

if (ff) printf("yes\n");else

printf("no\n");

}return

0;}

785 快速排序

題目描述 給定你乙個長度為n的整數數列。請你使用快速排序對這個數列按照從小到大進行排序。並將排好序的數列按順序輸出。輸入格式 輸入共兩行,第一行包含整數 n。第二行包含 n 個整數 所有整數均在1 10 9 109 範圍內 表示整個數列。輸出格式 輸出共一行,包含 n 個整數,表示排好序的數列。資料...

785 快速排序 c c

給定你乙個長度為n的整數數列。請你使用快速排序對這個數列按照從小到大進行排序。並將排好序的數列按順序輸出。輸入格式 輸入共兩行,第一行包含整數 n。第二行包含 n 個整數 所有整數均在1 109範圍內 表示整個數列。輸出格式 輸出共一行,包含 n 個整數,表示排好序的數列。資料範圍 1 n 1000...

Acwing 785 快速排序

給定你乙個長度為n的整數數列。請你使用快速排序對這個數列按照從小到大進行排序。並將排好序的數列按順序輸出。輸入格式 輸入共兩行,第一行包含整數 n。第二行包含 n 個整數 所有整數均在1 109109範圍內 表示整個數列。輸出格式 輸出共一行,包含 n 個整數,表示排好序的數列。資料範圍 1 n 1...