woj 1537 Stones I
题目地址: 戳这里
这是个比较好的思维题 ,简单但是有意思;
题面叙述不是很清楚
但是最后转化为数学模型就是:
选出一个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; } }
posted on 2014-03-31 00:15 814jingqi的ACM 阅读(237) 评论(0) 编辑 收藏 举报