竞赛总分

题目描述:

学生在我们USACO的竞赛中的得分越多我们越高兴。我们试着设计我们的竞赛以便人们能尽可能的多得分。
现在要进行一次竞赛,总时间T固定,有若干类型可选择的题目,每种类型题目可选入的数量不限,每种类型题目有一个si(解答此题所得的分数)和ti(解答此题所需的时间),现要选择若干题目,使解这些题的总时间在T以内的前提下,所得的总分最大。

输入包括竞赛的时间,M(1 <= M <= 10000)和题目类型数目N(1 <= N <= 10000)。
后面的每一行将包括两个整数来描述一种"题型":

第一个整数说明解决这种题目能得的分数(1 <= points <= 10000);

第二整数说明解决这种题目所需的时间(1 <= minutes <= 10000)。

输入:

第 1 行:
两个整数:竞赛的时间M和题目类型数目N。
第 2-N+1 行:
两个整数:每种类型题目的分数和耗时。

输出:

单独的一行,在给定固定时间里得到的最大的分数。

样例输入:

300 4
100 60
250 120
120 100
35 20

样例输出:

605

先来一个一维的代码:

#include<iostream>
    #include<algorithm>
    #define BY Zhoier
    using namespace std;
    int dp[10010],ti[10010],si[10010];
    int k,n,m;
    int main()
    {
        scanf("%d%d",&m,&n);
        for (int i=1;i<=n;i++) 
            scanf("%d%d",&si[i],&ti[i]);
        for (int i=1;i<=n;i++)
            for (int j=ti[i];j<=m;j++)
            {
                dp[j]=max(dp[j],dp[j-ti[i]]+si[i]);
                k=max(k,dp[j]);
            }
        printf("%d",k);
        return 0;
    }

这道题首先想到的是DP,那么建一个一维或者二维的都是可以的。那么DP最重要的就是转移方程了,咱先列一个一维的:对于每一种不同题型的前几项时间加和(不包括自己),就是dp[j-ti[i]]+si[i];在max函数中,dp[j]代表不处理该数据,也就是在满足上面的for循环的前提下,这个dp的值不变,所以会执行该语句再往下走;如果执行的是后面的语句,则可以更新dp的值。

k的作用当然显而易见了,只做一个更新的作用就可以了。

PS:数组要尽量开大点……要不然……后果自负-_-

原文地址:https://www.cnblogs.com/Zhoier-Zxy/p/8067479.html