题目地址: 戳这里
这是个比较好的思维题 ,简单但是有意思;
题面叙述不是很清楚
但是最后转化为数学模型就是:
选出一个k元子集(不妨设为1,2,3,...,k)
使得 a[1]-b[1]-b[2]-...-b[k];
+a[2]-b[1]-b[2]-...-b[k];
+a[3]-b[1]-b[2]-...-b[k];
+...
+a[k]-b[1]-b[2]-...-b[k];
是最大的。
公式变形一下,就是sigma a[i]-k*b[i];
可以看见,这k个数选进来的顺序是没有影响的,而且必定是最大的k个(a[i]-k*b[i]) ,否则就可以替换使之更大。
然后就暴力枚举k了,关于每一项都必须是正数,证明是显然的。
代码:
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
int a[1005];
int b[1005];
int c[1005];
int ans[1005];
bool cmp(int a,int b)
{
return a>b?1:0;
}
int main()
{
int n;
while(cin>>n)
{
if(!n) break;
memset(c, 0, sizeof(c));
memset(ans, 0, sizeof(ans));
for(int i=0;i<n;i++)
{
cin>>a[i]>>b[i];
}
for(int k=0;k<=n;k++)
{
for(int i=0;i<n;i++)
c[i]=a[i]-k*b[i];
sort(c,c+n,cmp);
if(c[k-1]<0) continue;
for(int i=0;i<k;i++)
ans[k]+=c[i];
}
int max=-1;
for(int i=0;i<=n;i++)
if(ans[i]>max) max=ans[i];
cout<<max<<endl;
}
}