【問題描述】
有乙個古老的石頭遊戲,該遊戲基於任意一棵樹t,遊戲的目標是在樹t的根節點上放一顆石頭,遊戲的規則如下:
1、 遊戲開始前,玩家先將k個石頭放入桶中。
2、 在遊戲的每一步,玩家從桶中拿一顆石頭放到樹的乙個空的葉子節點上。
3、 當乙個節點p的所有r個子節點都有乙個石頭,則移去r個子節點上的石頭,然後將乙個石頭放到節點p上。剩下的r-1個石頭重新放到桶中重複使用。
如果玩家根據以上規則放置石頭,並最終在根節點上放置一顆石頭,則贏得遊戲。
現在的任務是求出遊戲開始時,石頭數k的最小值,使得玩家能在給定樹的情況下贏得遊戲。
【輸入格式】
第一行輸入測試用例的個數t,每個測試用例是一顆樹的描述。第二行開始輸入每棵樹的描述。
每棵樹有n個節點,節點標號為1,2,…n,每個節點可以有任意個子節點,根節點標號為1,。樹的描述第一行為節點數n,第二行開始按照節點標號順序描述n個節點的子節點,每行第乙個數為標號p,第二個數為子節點數r,如果r不為0,接下來為r個子節點的標號。
【輸出格式】
對每棵樹,輸出石頭數的最小值。
【輸入樣例】
2 7
1 2 2 3
2 2 5 4
3 2 6 7
4 0
5 0
6 0
7 0
12 1 3 2 3 4
2 0
3 2 5 6
4 3 7 8 9
5 3 10 11 12
6 0
7 0
8 0
9 0
10 0
11 0
12 0
【輸出樣例】
3 4
【資料範圍】
1<=t<=10 n<200
題意:
給出一棵一般的樹,按如下的三種規則在樹上放石子:
1,在遊戲開始時,玩家可以拿k個石子放在水桶裡。
2,在遊戲的每一步,玩家可以從水桶裡拿出乙個石子,並放在任意乙個空的葉子上。
3,當乙個父節點的r個子節點都被放上了乙個石子,可以將這r個石子都拿去並在父節點上放乙個石子。水桶裡石子可以再次使用。
顯然,最終根上會被放上乙個石子,問的是,求用最少的石子達到上述要求,求這個最小值。(有很多k,求最小的那個);
思路: 設所求結果用result來表示,我們要求的是以1為根的result,這個結果必定依賴於它的子節點的相關資訊。這個資訊會是什麼呢?
考慮一棵樹的子孫是該樹的子樹。假設1的子孫分別為r1,r2,r3。那麼r1,r2,r3,都是1的子樹的根。假設以r1,r2,r3為根的上述結果分別為result1,result2,result3,顯然它們之和一定能達到1上也能被放上石子的目的。那這個值是不是最小的呢?假設result1>=result2>=result3,我們用result1個石子讓r1上放上了乙個石子,此時我們剩餘了result1-1個石子沒有用,這些石子可以彌補result2,最終可能會得到乙個更小的值(<=result1+result2+result3,通過對先前石子的重複利用)。如何安排這種彌補方式呢?
最大值優先。r1需要的石子result1最大,那麼最終的結果必定result>=result1,然而最終只需在r1上放乙個石子,留下了result1-1個石子。
那麼r1 ,r2一共需要result = result1+result2-min( result-1,result2 )個石子,其中min(result1-1,result2)被加了兩次,所以要減掉一次。
這樣r1,r2就合併成了乙個節點,最少需要result個石子,那麼result=result+result3-min(result-2,result3)。最終得解。
顯然這是乙個貪心演算法,符合貪心選擇和最優子結構
#include
#include
#include
#include
#include
#include
#define mod 10007
#define maxn 505
#define oo 100000000
using
namespace
std;
int n,t;
int sz[maxn],d[maxn],g[maxn][maxn];
void read(int &x)
if(ok) x=-x;
}void dfs(int i)
int cnt=0,a[300];
for(int k=1;k<=sz[i];k++)
sort(a+1,a+cnt+1);
int num=a[cnt]-1,sum=a[cnt];
for(int k=cnt-1;k>=1;k--)
if(a[k]>num) sum+=(a[k]-num);
d[i]=sum;
}void task()
void in()
task();
}}int main()
回文回文數 HUST 1694
problem 如果乙個數從左往右讀和從右往左讀都是一樣,那麼這個數就叫做 回文數 事實上,有一些數 如 21 在十進位制時不是回文數,但在其它進製 如二進位制時為 10101 時就是回文數。現在,你需要找出來,前 n 個滿足大於 s 且在兩種或兩種以上進製 二進位制至十進位制 上是回文數的十進位制...
POJ 1753 POJ 2965 解題報告
poj 1753 poj 2965 解題報告 poj 1753 和 poj 2965 是同一型別的題目,但是2965 有乙個比較簡單的方法來解決。poj 1753 我用的是打表的方法,打表很不厚道。思路 首先我們需要確定儲存的資料結構,從網上搜得用二進位制位來存,這確實是個很巧妙的方法,例如,我們將...
poj 3074 poj 3076(精確覆蓋)
兩個題都是數獨,題意很明確。建圖的思路大神寫的很好 行 一共9 9 9 729行。一共9 9小格,每一格有9種可能性 1 9 每一種可能都對應著一行。列 一共 9 9 9 9 81 324 種前面三個9分別代表著9行9列和9小 塊。乘以9的意思是9種可能,因為每種可能只可以選擇乙個。81代表著81個...