【CSP-J 2019】纪念品

题目简要

小伟突然获得一种超能力,他知道未来T天N种纪念品每天的价格。某个纪念品的价格是指购买一个该纪念品所需的金币数量,以及卖出一个该纪念品换回的金币数量。

每天,小伟可以进行以下两种交易无限次:

1.任选一个纪念品,若手上有足够金币,以当日价格购买该纪念品;

2.卖出持有的任意一个纪念品,以当日价格换回金币。 每天卖出纪念品换回的金币可以立即用于购买纪念品,当日购买的纪念品也可以当日卖出换回金币。当然,一直持有纪念品也是可以的。

T 天之后,小伟的超能力消失。因此他一定会在第 T 天卖出所有纪念品换回金币。 小伟现在有 M    枚金币,他想要在超能力消失后拥有尽可能多的金币。

输入格式、样例

输入文件名为 souvenir.in。 第一行包含三个正整数 T, N, M,相邻两数之间以一个空格分开,分别代表未来天数 T,纪念品数量 N,小伟现在拥有的金币数量M。 接下来T行,每行包含 N 个正整数,相邻两数之间以一个空格分隔。第i行的N 个正整数分别为 Pi,1, Pi,2, … … , Pi,

6 1 100 50 20 25 20 25 50

输出格式、样例

输出文件名为 souvenir.out。 输出仅一行,包含一个正整数,表示小伟在超能力消失后最多能拥有的金币数量。305

其他

【输入输出样例 1 说明】 最佳策略是: 第二天花光所有 100 枚金币买入 5 个纪念品 1; 第三天卖出 5 个纪念品 1,获得金币 125 枚; 第四天买入 6 个纪念品 1,剩余 5 枚金币; 第六天必须卖出所有纪念品换回 300 枚金币,第四天剩余 5 枚金币,共 305 枚金币。 超能力消失后,小伟最多拥有 305 枚金币。

【数据规模与约定】 对于 10% 的数据,T=1。 对于 30% 的数据,T≤4,N≤4,M≤100,所有价格 10≤Pi,j​≤100。 另有 15% 的数据,T≤100,N=1。 另有15% 的数据,T=2,N≤100。 对于 100% 的数据,T≤100,N≤100,M≤103,所有价格1≤Pi,j​≤104,数据保证任意时刻,小明手上的金币数不可能超过 10^4。

分析

dp完全背包。

#include<bits/stdc++.h>
using namespace std;
long long t,n,m;//未来天数 T,纪念品数量 N,小伟现在拥有的金币数量M。
long long a[110][1010];//第i天第j件价格
long long f[10010];
int main()
{
    cin>>t>>n>>m;
    for(int i=1;i<=t;i++)
    {
        for(int j=1;j<=n;j++)
        {
            cin>>a[i][j];//输入
        }
    }
    int ans=m;//一开始没买,可认为盈利m元。
    for(int T=2;T<=t;T++)//从第二天开始买。
    {
        memset(f,-0x7f,8*10010);//设置f全为-0x7f.
        f[0]=0;//0元换来0元的盈利。
        for(int i=1;i<=n;i++)
        {
            for(int j=0;j<=ans;j++)//f[j]:j元获得的最大利润。so,枚举从0到ans(拥有的钱)
            {
                if(f[j]!=-0x7f7f7f7f)//可转移
                {
                    f[j+a[T-1][i]]=max(f[j+a[T-1][i]],f[j]+a[T][i]-a[T-1][i]);
                                        //f[j+a[T-1][i]]:“超能力”相当于第T天可用第T-1天的money买东西,所以此意为:花费j+昨天价格的这样东西获得最大利润。f[j]+a[T][i]-a[T-1][i]:j元+今天价-昨天价(利润)获得的最大利润。
                }
            }
        }
        long long we=0;
        for(int k=1;k<=ans;k++)
        {
            we=max(we,f[k]);//打一次擂台,比较最值。
        }
        ans+=we;
    }
    cout<<ans;//结束!
    return 0;
}
上一篇
下一篇