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

来源:互联网 发布:金融富豪 知乎 编辑:程序博客网 时间:2024/06/03 05:47

大家羊年新年快乐啊!


这道题很适合年三十做,很涨自信。应该是马年做的最后一道题啦


这道题其实真的跟动态规划有关系吗?虽然满足最优子结构,但并没有重叠子问题。因此只是一道普通的树的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 Crisischar 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;}

0 0
原创粉丝点击