<textarea cols="89" rows="15" name="code" class="cpp">//poj 1040 Transportation (搜索+剪枝) /* 题解:排序,所有order从左到右搜,决定选或不选 PS:一个小小剪枝产生的效果大极了,剪枝前TLE,剪枝后200多MS */ #include <iostream> #include <algorithm> #include <cmath> using namespace std; const int inf = 1<<28; int n,m; int c,ans,mark; struct node { int from,to,num,gain; bool operator < (const node & other) const { if (from==other.from) return to<other.to; return from<other.from; } }ord[22]; void dfs(int step,int sum,int earn,int mark) { if (step>=n) { ans=max(ans,earn); return ; } //以下三行为剪枝 int temp=earn; for (int i=step;i<n;i++) temp+=ord[i].gain; if (temp<ans) return ; for (int i=0;i<step;i++) if ( ((1<<i)&mark) && ord[i].to<=ord[step].from) sum-=ord[i].num,mark^=(1<<i); dfs(step+1,sum,earn,mark); if (ord[step].num+sum>c) return ; dfs(step+1,sum+ord[step].num,earn+ord[step].gain,mark|(1<<step)); } int main() { while (scanf("%d%d%d",&c,&m,&n) && c+m+n) { for (int i=0;i<n;i++) { scanf("%d%d%d",&ord[i].from,&ord[i].to,&ord[i].num); ord[i].gain=ord[i].num*(ord[i].to-ord[i].from); } sort(ord,ord+n); ans=mark=0; dfs(0,0,0,0); printf("%d/n",ans); } system("pause"); return 0; } </textarea>