luogu P2430 嚴酷的訓練 題解

 

By:Soroaknode

 

知識點:DP

思路:就是一道簡單的DP
一開始我想用二維數組作
作着作着發現,沒有那麼難啊啊啊
徹底能夠用一維數組來作

咱們先開兩個一維數組來存每一個題目的時間
一個是老王的時間,另外一個是wky的時間,
(其實徹底能夠用一個一位數組寫的。。)
ios

再開一個結構體,來存每個題目的知識點種類和作出該題目的價值數組


而後雙重循環,第一層從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);
ide

 

/*    
    知識點: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
相關文章
相關標籤/搜索