Problem description is http://acm.uva.es/p/v100/10026.html
Seems like a zero-one-knapsack, but a little more twisted. It took lots of time not because the complexity of the given problem, but because of the STL chores. -_-;;
I’d better read STL book again.
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
#define MAX_INTEGER_VALUE 99999
// Represents each job
class Job {
public:
int time;
int fine;
int ID;
Job() {}
Job(int ID, int time, int fine):ID(ID), time(time), fine(fine) {}
};
class JobTimeLess {
public:
bool operator()(const Job &lhs, const Job &rhs) const {
return lhs.time < rhs.time;
}
};
class EqualID {
private:
int ID;
public:
EqualID(Job job) {
ID = job.ID;
}
bool operator()(const Job &j) const {
return j.ID == ID;
}
};
class Stage {
public:
vector<Job> remained;
int totalFine;
Job jobFinished;
Stage():totalFine(MAX_INTEGER_VALUE) {}
Stage::~Stage() {}
};
int totalTime() {
return 3+1+2+5;
}
Stage getTimeZero() {
Stage stage;
stage.remained.push_back(Job(1,3,4));
stage.remained.push_back(Job(2,1,1000));
stage.remained.push_back(Job(3,2,2));
stage.remained.push_back(Job(4,5,5));
return stage;
}
void dumpStage(Stage &s) {
cout << "Remained Jobs" << endl;
vector<Job>::iterator i;
for (i = s.remained.begin() ; i != s.remained.end() ; i++)
cout <<"ID: " << (*i).ID
<< " Time: " << (*i).time
<< " Fine: " << (*i).fine << endl;
}
int computeFine(Stage &stage, Job job) {
int fine = 0;
vector<Job>::iterator i;
for (i = stage.remained.begin() ; i != stage.remained.end() ; i++) {
fine += (*i).fine;
}
return stage.totalFine + fine * job.time;
}
inline bool isLowerCost(Stage &target, Stage &stage, Job &job) {
int fine = computeFine(stage, job);
if (target.totalFine > fine)
return true;
// lexicographical ordering consideration
else if (target.totalFine == fine && target.jobFinished.ID > job.ID)
return true;
return false;
}
int main() {
vector<Stage> stages(totalTime() + 1);
stages[0] = getTimeZero();
stages[0].totalFine=0;
for (int timeIdx = 0 ; timeIdx < totalTime() ; timeIdx++) {
vector<Job>::iterator i;
Stage &stage = stages[timeIdx];
cout << "Time:" << timeIdx << endl;
cout << "Considering..." << endl;
dumpStage(stage);
for (i = stage.remained.begin() ; i != stage.remained.end() ; i++) {
Job job = *i;
Stage &target = stages[timeIdx + job.time];
if (isLowerCost(target, stage, job)) {
// Set finished job
target.jobFinished = job;
// New total fine
target.totalFine = computeFine(stage, job);
// Copying remained jobs,
// excluding the job finished
target.remained = vector<Job> (stage.remained);
vector<Job>::iterator r =
find_if(target.remained.begin(),
target.remained.end(),
EqualID(job));
target.remained.erase(r, r+1);
}
}
}
int timeIdx = totalTime();
cout << "Result" << endl;
while(timeIdx > 0) {
Stage stage = stages[timeIdx];
cout << "Time: " << timeIdx << " Job: " << stage.jobFinished.ID << endl;
timeIdx = timeIdx - stage.jobFinished.time;
}
return 0;
}
The answer is: 2 1 3 4
Comments 4
0-1knapsack 이지만
Posted 24 Jun 2004 at 6:05 pm ¶branch and bound 로 풀면 더 빠르지 않을까여 ㅋㅋㅋ
잘 봤습니다. 역시 3년의 공백이 크다는 것을 실감할 뿐이군요. ^^
kanpsack 문제와 비슷하게 생각했지만…(순열문제)
Posted 24 Jun 2004 at 7:32 pm ¶그나마, 비슷한 생각을 했다는데 만족해야할 듯…^^
진규/어.. 너의 한마디가 내 리써치에 큰 영향을 줄거 같다. 그렇지.. dynamic을 branch and bound로 푼다라..
trax/ 별말씀을 -_-; 저 지저분한 코드(단지 문제만 풀기 위한)를 보고 그런말씀을 하다니..
Posted 25 Jun 2004 at 1:36 am ¶음 그거 읽었어여..
trax씨 블로그도 rss 리더에 넣었음. ^^;;;
세상에 똑똑한 사람 많아요~
Posted 08 Jul 2004 at 11:50 pm ¶Post a Comment