比较简单的回溯,不过需要注意的是,遍历的时候需要加一个cur参数避免重复访问之前已经访问过的订单,AC了。。不过卡时间卡到了2S。。。。勉强过了
#include<cstdio>
#include<cstring>
#include<iostream>
#include<iostream>
using namespace std;
#define MAX_SIZE 100
int L,n,m;
struct Bill{
int from; /*起始地*/
int to; /*目的地*/
int pas; /*乘客数量*/
int sum; /*订单总金额*/
}bill[MAX_SIZE];
int visa[MAX_SIZE]; /*记录订单是否被访问过*/
int state[MAX_SIZE];/*当前载客人数*/
int SUM,MIN;
void dfs(int cur){
for(int i = cur;i < m;i++)
if(!visa[i]) /*如果这个订单没有被看过*/{
int temp[MAX_SIZE];
int ok = 1;
memcpy(temp,state,sizeof(state));
for(int j = bill[i].from ; j< bill[i].to;j++) /*检查*/{
state[j] += bill[i].pas;
if(state[j] > n){ok = 0;break;}
}
if(ok){
visa[i] = 1; /*表示访问过了*/
SUM += bill[i].sum;/*总和要加上*/
dfs(i + 1);
}
/*状态还原*/
visa[i] = 0;
memcpy(state,temp,sizeof(temp));
if(ok) SUM -= bill[i].sum;
}
MIN = MIN > SUM? MIN:SUM;
return ;
}
int main(){
while(scanf("%d%d%d",&n,&L,&m)!=EOF){
if(!L&&!n&&!m) break;
memset(visa,0,sizeof(visa));
memset(state,0,sizeof(state));
SUM = 0;
MIN = 0;
for(int i = 0;i < m;i++){
scanf("%d",&bill[i].from);
scanf("%d",&bill[i].to);
scanf("%d",&bill[i].pas);
bill[i].sum = (bill[i].to - bill[i].from)*bill[i].pas;
}/*输出订单的基本信息*/
dfs(0);
printf("%d\n",MIN);
}
return 0;
}