竞赛总分(简单dp之完全背包问题)

竞赛总分
总时间限制: 1000ms 内存限制: 65536kB
描述
学生在我们USACO的竞赛中的得分越多我们越高兴。我们试着设计我们的竞赛以便人们能尽可能多得分。
现在要进行一次竞赛,总时间T固定,有若干类型可选择的题目,每种类型题目可选入的数量不限,每种类型题目有一个si(解答此题所得的分数)和ti(解答此题所需的时间),现要选择若干题目,使解这些题的总时间在T以内的前提下,所得的总分最大。
输入包括竞赛的时间M和题目类型数目N。
后面的每一行将包括两个整数来描述一种”题型”:
第一个整数说明解决这种题目能得的分数points,第二整数说明解决这种题目所需的时间minutes。
输入
第 1 行:两个整数:竞赛的时间M和题目类型数目N。
第 2-N+1 行:两个整数:每种类型题目的分数和耗时。
输出
单独的一行,在给定固定时间里得到的最大的分数。
样例输入

300 4
100 60
250 120
120 100
35 20

样例输出

605

提示

【数据规模】
1 <= M <= 10000
1 <= N <= 10000
1 <= points <= 10000
1 <= minutes <= 10000

思路点拔:一看到这种题有两个参数,就想到是0-1背包问题还是完全背包问题,但是本题是没有个数限制的,所以就是一个经典的完全背包问题,状态转移方程是dp[j]=max(dp[j],dp[j-w[i]]+c[i]),就不用多说了吧,实在不行就看一本通的352——353页,上代码!!!

#include //再次建议不要用万能头文件
#include
using namespace std;
const int MAXN=10005;
int v[MAXN],t[MAXN],dp[MAXN]; //v数组是分数,t数组是时间
int main()
{
    int m,n;
    scanf("%d %d",&m,&n); 
    for(int i=1;i<=n;i++)
    {
        scanf("%d %d",&v[i],&t[i]);
    }
    for(int i=1;i<=n;i++) //外层循环枚举物品数
    {
        for(int j=t[i];j<=m;j++) //注意内层循环是正序查找,反序就是错的
        {
            dp[j]=max(dp[j],dp[j-t[i]]+v[i]); //dp
        }
    }
    printf("%d",dp[m]); //输出解
    return 0; //结束
}

你可能感兴趣的:(dp)