大家羊年新年快樂啊!
這道題很適合年三十做,很漲自信。應該是馬年做的最後一道題啦
這道題其實真的跟動態規劃有關係嗎?雖然滿足最優子結構,但並沒有重疊子問題。因此只是一道普通的樹的dfs而已。
關於求最少人數的式子:(k*T - 1)/100 + 1
k*T/100不需要解釋。一個-1一個+1則起到了手動ceiling的功能。
因爲整數除法是自動floor,所以+1就是將其變成ceiling。但如果整數除法得出的結果恰恰本身就是一個整數,那麼+1將導致錯誤的結果。這時就需要在整數除法前,在被除數上減去一個比較小的正數(epsilon)(epsilon的大小和後面的+1沒有關係),從而使後面的+1可以正常工作。epsilon要足夠小,從而不影響整數除法的正確性,比如(101-e)/100+1,e應小於1,否則式子得數會錯誤的變爲1。
Run Time: 0.239s
#define UVa "LT9-12.12186.cpp" //Another Crisis
char fileIn[30] = UVa, fileOut[30] = UVa;
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<vector>
using namespace std;
//Global Variables. Reset upon Each Case!
const int maxn = 100000 + 10;
int N, T;
vector<int> S[maxn];
/////
int dp(int i) {
if(S[i].size() == 0) return 1; //leaf node
else {
vector<int> tmp;
for(int j = 0; j < S[i].size(); j ++)
tmp.push_back(dp(S[i][j]));
sort(tmp.begin(), tmp.end());
int ans = 0;
for(int j = 0; j < (S[i].size() * T -1) / 100 + 1; j ++)
ans += tmp[j];
return ans;
}
}
int main() {
while(scanf("%d%d", &N, &T) && N) {
for(int i = 0; i <= N; i ++) S[i].clear();
int b;
for(int i = 1; i <= N; i ++) {
scanf("%d", &b);
S[b].push_back(i);
}
printf("%d\n", dp(0));
}
return 0;
}