几天作了一个题目,使用到了动态规划思想,避免重复计算的重要性。不避免重复计算,程序通不过测试(超时),而避免了重复计算,速度明显加快。
问题描述:
格式如:" s t p"表示一个比赛开始的时间为s 结束时间为t 胜出的可能为p(0--100)现在有一个vector<string>co,需要求一下参加比赛能使累计p得值为最大,比如参加3场比赛,把p累计得q,即求得能得到q,求q的最大值。
You will be given a vector <string> contests. Each element of contests represents a single contest and is formatted as "s t p" (quotes for clarity only), where s, t, and p are all integers. Each contest starts at time s and ends before time t, and John estimates that there is a p percent probability of winning that contest. Return the maximal expected number of contests that John will win if he participates in the optimal subset of non-conflicting contests. |
解决:采用递归的做法。先按照开始时间排序,然后依次选第一个比赛,然后求出剩余比赛中能参加的最大值,显然,这是一个递归。如果按照这样做,效率很低,大量的重复计算,比如,已经求得了参加第i个比赛的最大值,在递归过程中,所有参加第i个比赛时都需要重新计算一遍。现在有一个vector<int>m来记录参加第i个比赛时的最大值,只需要在第一次参加时递归求出改值k,使得m[i]=k,下一次是参加时值需要从m中读取m[i]。为了避免计算量,可以从最后一个元素开始,m[len]=第len个元素的胜率,然后递减计算,第i个肯定是依赖于第i+1--end得。所以,避免了重复递归计算。最后只需要求出m中的最大值即可。
程序:
#include <set>
#include <vector>
#include <string>
#include <map>
#include <iostream>
#include <iterator>
#include <algorithm>
#include <stdio.h>
#include <complex>
#include <sstream>
#include <math.h>
#include <ctype.h>
//isalnum(), isalpha(), iscntrl(), isgraph(), isprint(), ispunct(), and isspace(),isdigit(),
#define cp(cot,type) copy(cot.begin(),cot.end(),ostream_iterator<type>(cout," "));cout<<endl
#define repn(i,n) for(int i = 0; i < n; i++)
#define repc(i,a) for(int i = 0; i < a.size(); i++)
using namespace std;
class cmp
{
public:
bool operator()(string s1,string s2)
{
int a1,a2;
sscanf(s1.c_str(),"%d",&a1);
sscanf(s2.c_str(),"%d",&a2);
// cout<<a1<<" "<<a2<<endl;
return a1<=a2;
}
};
class ContestSchedule
{
private:
int f(vector<int>&s,vector<int>&t,vector<int>&p,int b,int lt,int max,vector<int>&m)
{
if(b==t.size())
return max;
int tmp=0 ;
int tm=max;
for(int i = b; i < s.size();i++)
{
if(s[i]>=lt)
{
if(m[i]==0)
{
tmp =f(s,t,p,i+1,t[i],0,m);
tmp+=p[i];
m[i]=tmp;;
}else tmp=m[i];
if(tmp>tm)
tm=tmp;
}
}
return tm;
}
public:
double expectedWinnings(vector <string> contests)
{
int len = contests.size();
sort(contests.begin(),contests.end(),cmp());
vector<int>s(len,0);
vector<int>t(len,0);
vector<int>p(len,0);
vector<int>m(len,0);
// cout<<sizeof(int)<<endl;
for(int i = 0; i<len;i++)
sscanf(contests[i].c_str(),"%d %d %d",&s[i],&t[i],&p[i]);
// cp(s,int);
//cp(t,int);
// cp(p,int);
int ret=0;
for(int i = len -1; i >= 0;i--)
{ ret = f(s,t,p,i,0,0,m);
m[i]=ret;
}
sort(m.begin(),m.end());
cp(m,int);
return double(m[len-1])/100;
}
};