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;
}

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