9.13(垦田计划(差分),现值计算)

第一题,垦田计划,本来以为把每一块田的天数和要投入的资源数都存一下,然后排个序,从大的开始往后减,遇到不小于自身天数的就回溯到第一个(因为这样下来排序为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;
}	


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值