题解:P9225 「PEOI Rd1」寻宝(treasure)
集训听了贪心的做法,乃大惊,遂写题解记录。
就拿第二个样例举例:
3
1 2 100
1 2 1
第
对于第
同理,对于新的序列,我们仍然只会使用它偶数次。相邻两项合并得到
由于答案不会超过
::::info[code]
#include<bits/stdc++.h>
using namespace std;
const int N=1e3+10,M=1e4+10;
int n,a[N],b[N],totc,totd;long long c[M],d[M],tmp[M];
void merge(){
int i=1,j=1,tot=0;
while(i<=totc&&j<=totd){
if(c[i]<d[j])tmp[++tot]=c[i],i++;
else tmp[++tot]=d[j],j++;
}
while(i<=totc)tmp[++tot]=c[i],i++;
while(j<=totd)tmp[++tot]=d[j],j++;
for(int k=1;k<=tot;k++)c[k]=tmp[k];
totc=tot;
}
signed main(){
ios::sync_with_stdio(0);
cin.tie(0);cout.tie(0);
cin>>n;
for(int i=1;i<=n;i++)cin>>a[i];
for(int i=1;i<=n;i++)cin>>b[i];
for(int i=1;i<=n;i++){
int now=a[i],sum=0;totd=0;
for(int j=1;;j++){
sum+=now;
if(sum>a[n])break;
d[++totd]=now;
now+=b[i];
}
if(i==1){for(int j=1;j<=totd;j++)c[++totc]=d[j];}
else{
int netot=0;
for(int j=1;j<=totc;j++){
if(j*2>totc)break;
c[j]=c[j*2-1]+c[j*2];
netot=j;
}
totc=netot;
merge();
}
}
cout<<c[1];
return 0;
}
::::