UVa #12186 Another Crisis (例題9-12)

大家羊年新年快樂啊!


這道題很適合年三十做,很漲自信。應該是馬年做的最後一道題啦


這道題其實真的跟動態規劃有關係嗎?雖然滿足最優子結構,但並沒有重疊子問題。因此只是一道普通的樹的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;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章