luogu P2430 严酷的训练 题解

 

By:Soroak

 

知识点:DP

思路:就是一道简单的DP
一开始我想用二维数组做
做着做着发现,没有那么难啊啊啊
完全可以用一维数组来做

我们先开两个一维数组来存每个题目的时间
一个是老王的时间,另一个是wky的时间,
(其实完全可以用一个一位数组写的。。)

再开一个结构体,来存每一个题目的知识点种类和做出该题目的价值


然后双重循环,第一层从1到m,枚举所有的题目
第二层从tim到num[timu[i].kind],表示从tim时间开始,枚举到当前题目要花费的时间为止
Q:那为什么不直接枚举到1呢??
A:当j<num[timu[i].kind]时,枚举的时间小于该题目用的时间,那么数组的下标会成为负数,而且你怎么可能时间到了还在做题呢?

然后,就可以得到一个很简单的DP方程式: dp[j]=max(dp[j],dp[j-num[timu[i].kind]]+timu[i].value);

 

/*    
    知识点:DP 
    
    思路:就是一道简单的DP
    一开始我想用二维数组做
    做着做着发现,没有那么难啊啊啊
    完全可以用一维数组来做
    
    我们先开两个数组来存每个题目的时间
    一个是老王的时间,另一个是wky的时间,
    (其实完全可以用一个一位数组写的。。) 
    
    然后双重循环,第一层从1到m,枚举所有的题目
    第二层从tim到num[timu[i].kind],表示从tim时间开始,枚举到当前题目要花费的时间为止 
    Q:那为什么不直接枚举到1呢??
    A:当j<num[timu[i].kind]时,枚举的时间小于该题目用的时间,那么数组的下标会成为负数,而且你怎么可能时间到了还在做题呢?
    
    然后,就可以得到一个很简单的DP方程式: dp[j]=max(dp[j],dp[j-num[timu[i].kind]]+timu[i].value);
    
*/
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define int long long int 

using namespace std;

int wky,laowang;
int m,n;

int a[1000010];//老王在做第i种题目时所花费的时间 
int dp[5010];
int num[1000010];//wky在做第i种知识点的题目时要花费的时间 

struct node
{
    int value;
    int kind;
}timu[1000010];

int tim;

inline int cmp(node a,node b)
{
    return a.value>b.value;
}

inline void init()
{
    cin>>wky>>laowang;
    cin>>m>>n;
    
    for(int i=1;i<=n;i++)
    {
        cin>>a[i];
        num[i]=a[i]*(laowang/wky);
    }
    
    for(int i=1;i<=m;i++)
    {
        cin>>timu[i].kind;
        cin>>timu[i].value;
    }
    
    cin>>tim;
}

inline void calc()
{
    for(int i=1;i<=m;i++)
    {
        for(int j=tim;j>=num[timu[i].kind];j--)
        {
            dp[j]=max(dp[j],dp[j-num[timu[i].kind]]+timu[i].value);
        }
    }
}

signed main()
{
    init();
    sort(timu+1,timu+m+1,cmp);//有没有一个样
    calc();
    cout<<dp[tim]<<endl;
    return 0;
}
View Code

 

posted @ 2019-10-17 15:19  Soroak  阅读(112)  评论(0编辑  收藏  举报