POJ-1949(模拟或DP)
2014-06-08 21:19
381 查看
一、很容易想到如下的模拟过程:
(0)使没有先决条件的工作进入服务窗口
(1)找到所有正在处理的工作中剩余所需时间最少的工作所需的时间T
(2)将所有窗口剩余所需时间减去T,如果该窗口的工作已经完成,则将其当做先决条件的工作所需的先决条件的数量减一,如果这一工作已经没有任何先决条件,则将其送入一个窗口开始进行服务
(3)如果所有窗口都已经没有在进行服务,则过程停止
根据以上步骤,很容易写出模拟代码:
have only chores 1,.K-1 as prerequisites."说明我们可以边读入边DP而不用保存节点信息:
从时间上来看,用了DP之后,速度并没有得到质的改变,目测是因为数据量太大,大部分时间消耗在了scanf上:
当大部分时间用在IO上时,改进算法的作用微乎其微
(0)使没有先决条件的工作进入服务窗口
(1)找到所有正在处理的工作中剩余所需时间最少的工作所需的时间T
(2)将所有窗口剩余所需时间减去T,如果该窗口的工作已经完成,则将其当做先决条件的工作所需的先决条件的数量减一,如果这一工作已经没有任何先决条件,则将其送入一个窗口开始进行服务
(3)如果所有窗口都已经没有在进行服务,则过程停止
根据以上步骤,很容易写出模拟代码:
#include <cstdio> #include <vector> #include <list> using namespace std; #define MAX 10001 struct Job{ int timeNeeded; int numberOfPrerequisites; vector<int> nextJobs; } arr[MAX]; int N; int getLeastTimeNeeded(const list<int>& jobList) { list<int>::const_iterator iter = jobList.begin(), eter = jobList.end(); int t = arr[*iter++].timeNeeded, i; for(; iter != eter; ++iter){ i = *iter; if(t > arr[i].timeNeeded) t = arr[i].timeNeeded; } return t; } void insertSubsequentJobs(list<int>& jobList, int doneID) { if(arr[doneID].nextJobs.empty()) return; for(int i = 0, n = arr[doneID].nextJobs.size(); i < n; ++i){ int j = arr[doneID].nextJobs[i]; if(--arr[j].numberOfPrerequisites == 0) jobList.push_front(j); } } int main() { //step 1: input job count scanf("%d", &N); //step 2: input job graph int i, j, k; for(i = 1; i <= N; ++i){ scanf("%d %d", &arr[i].timeNeeded, &arr[i].numberOfPrerequisites); for(j = 0; j < arr[i].numberOfPrerequisites; ++j){ scanf("%d", &k); arr[k].nextJobs.push_back(i); } } //step 3: initialize job line list<int> jobList; list<int>::iterator iter, eter; for(i = 1; i <= N; ++i){ if(arr[i].numberOfPrerequisites == 0) jobList.push_front(i); } //step 4: schedule jobs int totalTime = 0, time; while(!jobList.empty()){ //find out the job which need least time now totalTime += time = getLeastTimeNeeded(jobList); //minus each job with time for(iter = jobList.begin(), eter = jobList.end(); iter != eter; ){ i = *iter; arr[i].timeNeeded -= time; if(arr[i].timeNeeded == 0){ iter = jobList.erase(iter); insertSubsequentJobs(jobList, i); } else ++iter; } } //step 5: print result printf("%d", totalTime); return 0; }二、实际上此题还可以看做树型DP的问题,把每一个工作看成一个节点,将先决条件看成其子节点,则dp[parent] = max{dp[children] + costOfParent},并且题中"Farmer John's list of chores is nicely ordered, and chore K (K > 1) can
have only chores 1,.K-1 as prerequisites."说明我们可以边读入边DP而不用保存节点信息:
#include <cstdio> #define MAX 10001 int N, dp[MAX] = {0}; int main() { scanf("%d", &N); int i, j, k, n, t, ans = 0; for(i = 1; i <= N; ++i){ scanf("%d %d", &t, &n); if(n == 0) dp[i] = t; else{ for(j = 0; j < n; ++j){ scanf("%d", &k); if(dp[k] + t > dp[i]) dp[i] = dp[k] + t; } } if(dp[i] > ans) ans = dp[i]; } printf("%d", ans); return 0; }
从时间上来看,用了DP之后,速度并没有得到质的改变,目测是因为数据量太大,大部分时间消耗在了scanf上:
当大部分时间用在IO上时,改进算法的作用微乎其微
相关文章推荐
- POJ 1949 Chores(树状DP)
- POJ 1949 Chores(DP)
- POJ1949 DP基础题
- POJ 1949 Chores(树形dp)
- 【dp每一天】POJ - 1655 Balancing Act(说是树形dp其实就是模拟?)
- poj1949(拓扑,dp)
- (POJ DP1.1)POJ 1949 Chores(简单DP)
- POJ 1949 DP?
- POJ 1949 DP?
- POJ 1189 模拟/DP
- [poj 1949]Chores 题解 [dp]
- (POJ 1949)Chores DAG简单DP
- POJ 2000 Gold Coins(模拟)
- POJ 1083 Moving Tables(模拟)
- poj2479 DP重新50题
- POJ 2479 最大子段和dp
- POJ 2506 Tiling(DP+大数运算)
- POJ 1163 这才叫DP 当然有些过于典型了
- POJ 2260 Error Correction(模拟)
- POJ 1952 BUY LOW BUY LOWER 【DP】最长降序子序列及其计数问题