dfs+回朔
怎么样接受订单收益最大。
第一个数字是列车最大的容量,第二个是B的站点,第三个数字是订单的数量。
然后每个人每站路一元钱。所以要尽可能多的让人上车,但又不能超过最大容量。
用回朔法,从第一个订单开始接受,然后使要到达订单终点站和起点站之间的车站人数全部都加订单上的人数。
若超过容量,则直接返回。
#include<cstdio>
#include<cstring>
const int MAXN=30;
int pp[MAXN],n,B,m;
int maxearn;
typedef struct{
int ss,ds,pp; //起点,终点,和人数
}solve;
solve order[MAXN];
void dfs(int start,int money){
money += (order[start].ds-order[start].ss)*order[start].pp; //若进入,则未超过人数。加利润加上
if(money>maxearn) maxearn=money;
for(int i=start+1;i<m;i++){
bool ok=true; int j;
for(j=order[i].ss+1;j<=order[i].ds;j++){ //判断是否会超过火车的容量。
pp[j] += order[i].pp;
if(pp[j]>n) {ok=false;j++; break;}
}
if(ok) dfs(i,money);
for(int k=j-1;k>order[i].ss;k--) pp[k]-=order[i].pp; //不用回朔金额,因为进去之后才会加上该订单的金额
}
}
int main(){
//freopen("in.txt","r",stdin);
while(~scanf("%d%d%d",&n,&B,&m)){
if(n==0 && B==0 && m==0) break;
maxearn=0;
memset(pp,0,sizeof(pp));
for(int i=0;i<m;i++) scanf("%d%d%d",&order[i].ss,&order[i].ds,&order[i].pp);
for(int i=0;i<m;i++) if(order[i].pp<=n){
int j;
for(j=order[i].ss+1;j<=order[i].ds;j++) pp[j]+=order[i].pp;
dfs(i,0);
for(int k=j-1;k>order[i].ss;k--) pp[k]-=order[i].pp; //起点也需要回朔人数
}
printf("%d\n",maxearn);
}
return 0;
}