第一题,垦田计划,本来以为把每一块田的天数和要投入的资源数都存一下,然后排个序,从大的开始往后减,遇到不小于自身天数的就回溯到第一个(因为这样下来排序为1的田始终所需的天数最大,所以回溯时直接回溯到0就行)。本来以为这个思路已经足够巧妙,结果被卡时间复杂度了。
被卡的代码如下:
#include<bits/stdc++.h>
using namespace std;
#define ll long long
ll n,m,k;
typedef struct farm{
ll day;
ll money;
}farm;
bool compare(farm a,farm b)
{
if(a.day>b.day)
return true;
else
return false;
}
vector<farm> field;
int main()
{
cin>>n>>m>>k;
while(n--)
{
farm temp;
cin>>temp.day>>temp.money;
field.push_back(temp);
}
ll N=field.size();
sort(field.begin(),field.end(),compare);
ll min_day;
for(ll i=0;i<N;i++)
{
if(field[i].money<=m)
{
field[i].day--;
m-=field[i].money;
}
else
{
min_day=field[i].day;
if(min_day<k)
min_day=k;
break;
}
if(i!=N-1&&field[i].day>=field[i+1].day)
i=-1;
}
cout<<min_day;
return 0;
}
后来我转念一想,这题完全可以用类似差分的思想做,先把每个天数对应的钱数算好,比如我最大的是第7天,那我从第七天开始,把第七天降成第六天的资源数是第七天的资源,把第六天降成第五天的资源是第六天和第五天的资源数总和(因为此时第七天也变成了第六天),如此类推,可把时间复杂度降为O(n)。果然就过了,代码如下:
#include<bits/stdc++.h>
using namespace std;
#define ll long long
ll n,m,k;
ll day[100010];
int main()
{
ll max=0;
cin>>n>>m>>k;
while(n--)
{
ll tp_day,tp_money;
cin>>tp_day>>tp_money;
if(max<tp_day)
max=tp_day;
day[tp_day]+=tp_money;
}
ll sum=day[max];
while(max>k)
{
if(sum<=m)
m-=sum;
else
break;
sum+=day[--max];
}
cout<<max;
return 0;
}
第二题,现值计算,把题目读懂很简单的。代码如下:
#include<bits/stdc++.h>
using namespace std;
#define ll long long
ll n;
double p;
ll day[100010];
int main()
{
cin>>n>>p;
n=n+1;
double sum=0;
double i=1;
while(n--)
{
ll money;
cin>>money;
sum+=money*i;
i=1/(1+p)*i;
}
printf("%.5f",sum);
return 0;
}