prow2012-A3-0008
从 Trac 迁移的文章
这是从旧校内 Wiki 迁移的文章,可能存在一些样式问题,您可以向 memset0 反馈。
原文章内容如下:
自然界出题时我验的题目。
题意也记不清了,做法就是列出了方程后,很明显可以按比较法则决定哪些城市用于提升战斗力是最佳的。
{{{
bool comp(int i,int j){
//return (sum[N]-sum[i-1])*a[j]<(sum[N]-sum[j-1])*a[i];
return B*(sum[N]-sum[j-1])/a[i]+B/a[i]*(sum[j-1]-sum[i-1])/a[j]*(sum[N]-sum[j-1])
>=B/a[j]*(sum[N]-sum[j-1]);
}
}}}
比较两个城市优劣的方法,就是以i城市提升战斗力对之后的总获利,j城市提升战斗力对总获利作比较,决定出在i提升是否优于j。
贪心题可以这样比较优劣,如果从方程里没法决定出i j的优劣,那就是其他做法了。
{{{
#include <stdio.h>
#include <math.h>
#include <string.h>
#include <algorithm>
using namespace std;
double sum[110000],a[110000],b[110000];
int Q[110000];
int N;
double B,A;
bool comp(int i,int j){
//return (sum[N]-sum[i-1])*a[j]<(sum[N]-sum[j-1])*a[i];
return B*(sum[N]-sum[j-1])/a[i]+B/a[i]*(sum[j-1]-sum[i-1])/a[j]*(sum[N]-sum[j-1])
>=B/a[j]*(sum[N]-sum[j-1]);
}
int main(){
int i;
while(scanf("%d%lf%lf",&N,&B,&A)!=EOF){
sum[0] = 0;
for (i=1;i<=N;i++)
scanf("%lf%lf",&a[i],&b[i]),sum[i] = sum[i-1]+b[i];
int L =0,R = 0;
for (i=N;i>=1;i--)
if ((R==0&&sum[N]-sum[i-1]>a[i])||comp(i,Q[R-1]))
Q[R++] = i;
int t = 0;
for (i=1;i<=N;i++){
if (R>0&&i==Q[R-1]) {
if ((sum[N]-sum[i-1])>a[i]){
A+=B/a[i];
B = 0;
}
R--;
}
B+=A*b[i];
}
printf("%.2lf\n",B);
}
}
}}}
自然界出题时我验的题目。
题意也记不清了,做法就是列出了方程后,很明显可以按比较法则决定哪些城市用于提升战斗力是最佳的。
bool comp(int i,int j){
//return (sum[N]-sum[i-1])*a[j]<(sum[N]-sum[j-1])*a[i];
return B*(sum[N]-sum[j-1])/a[i]+B/a[i]*(sum[j-1]-sum[i-1])/a[j]*(sum[N]-sum[j-1])
>=B/a[j]*(sum[N]-sum[j-1]);
}
比较两个城市优劣的方法,就是以i城市提升战斗力对之后的总获利,j城市提升战斗力对总获利作比较,决定出在i提升是否优于j。
贪心题可以这样比较优劣,如果从方程里没法决定出i j的优劣,那就是其他做法了。
#include <stdio.h>
#include <math.h>
#include <string.h>
#include <algorithm>
using namespace std;
double sum[110000],a[110000],b[110000];
int Q[110000];
int N;
double B,A;
bool comp(int i,int j){
//return (sum[N]-sum[i-1])*a[j]<(sum[N]-sum[j-1])*a[i];
return B*(sum[N]-sum[j-1])/a[i]+B/a[i]*(sum[j-1]-sum[i-1])/a[j]*(sum[N]-sum[j-1])
>=B/a[j]*(sum[N]-sum[j-1]);
}
int main(){
int i;
while(scanf("%d%lf%lf",&N,&B,&A)!=EOF){
sum[0] = 0;
for (i=1;i<=N;i++)
scanf("%lf%lf",&a[i],&b[i]),sum[i] = sum[i-1]+b[i];
int L =0,R = 0;
for (i=N;i>=1;i--)
if ((R==0&&sum[N]-sum[i-1]>a[i])||comp(i,Q[R-1]))
Q[R++] = i;
int t = 0;
for (i=1;i<=N;i++){
if (R>0&&i==Q[R-1]) {
if ((sum[N]-sum[i-1])>a[i]){
A+=B/a[i];
B = 0;
}
R--;
}
B+=A*b[i];
}
printf("%.2lf\n",B);
}
}