vector 放到循环里,否则每次排序都是在原有的数据基础上。
本题贪心。
切记贪心核心思想
1.从局部出发,分析局部的特点,找局部的最优解,一般是问题的子问题。
2.局部扩展到全局,步步趋向最优,证明最优
现在考虑两个士兵X,Y的顺序。
假设只有两个战士,X士兵布置在前,Y士兵在后。
1)Xb+Xj > Xb+Yb+Yj ==>Xj > Yb+Yj==>Xj > Yj,若XY交换顺序,则Y完成的时间为Yb+Yj,X完成的时间为Yb+Xb+Xj > Xb +Xj,所以完成时间肯定会后延。
所以无需交换
2)Xb+Xj < Xb+Yb+Yj,交换后
1.Yb+Xb+Xj < Yb+Yj ==> Xb+Xj < Yj ==>Xj < Yj;此时Yb + Yj < Xb+Xj+Yj提前了,所以交换
2.Yb+Xb+Xj > Yb+Yj ;若要交换则只需满足Yb+Xb+Xj < Xb+Yb+Yj ==> Xj < Yj;
综上所述,两个士兵,J的值大的应当在前面。
而两个士兵的顺序交换是不影响其他士兵完成任务的,第三个士兵来时,应该按J大小排序,假设有n个士兵已经是最优解,当n+1个士兵是只要保持,第n+1个士兵放在按J排序的相应位置即可。
所以最终解应该是按J排序的序列。
[代码]
#include <iostream>
#include <malloc.h>
#include <algorithm>
#include <vector>
using namespace std;
const int MAX = 1000+5;
struct soldier
{
int b,j;
bool operator < (const soldier s) const
{
return j > s.j;
}
};
int main()
{
int n,cases= 1, b,j;
//struct soldiers[MAX];
while(scanf("%d",&n)== 1)
{
if(!n)break;
vector<soldier> soldiers;
int b_cost = 0,max_end = 0;
for(int i = 0; i < n; i++)
{
cin>>b>>j;
soldiers.push_back((soldier){b,j});
}
sort(soldiers.begin(),soldiers.end());
for(int i = 0; i < n; i++)
{
b_cost += soldiers[i].b;
max_end = max(max_end,b_cost+soldiers[i].j);
}
printf("Case %d: %d\n",cases++,max_end);
}
return 0;
}