#1038 : 01揹包 - #1043 : 完全揹包

#1038 : 01揹包

時間限制:20000ms

單點時限:1000ms

內存限制:256MB

描述

且說上一週的故事裏,小Hi和小Ho費勁心思終於拿到了茫茫多的獎券!而現在,終於到了小Ho領取獎勵的時刻了!

小Ho現在手上有M張獎券,而獎品區有N件獎品,分別標號爲1到N,其中第i件獎品需要need(i)張獎券進行兌換,同時也只能兌換一次,爲了使得辛苦得到的獎券不白白浪費,小Ho給每件獎品都評了分,其中第i件獎品的評分值爲value(i),表示他對這件獎品的喜好值。現在他想知道,憑藉他手上的這些獎券,可以換到哪些獎品,使得這些獎品的喜好值之和能夠最大。

提示一:合理抽象問題、定義狀態是動態規劃最關鍵的一步

提示二:說過了減少時間消耗,我們再來看看如何減少空間消耗

輸入

每個測試點(輸入文件)有且僅有一組測試數據。

每組測試數據的第一行爲兩個正整數N和M,表示獎品的個數,以及小Ho手中的獎券數。

接下來的n行描述每一行描述一個獎品,其中第i行爲兩個整數need(i)和value(i),意義如前文所述。

測試數據保證

對於100%的數據,N的值不超過500,M的值不超過10^5

對於100%的數據,need(i)不超過2*10^5, value(i)不超過10^3

輸出

對於每組測試數據,輸出一個整數Ans,表示小Ho可以獲得的總喜好值。

樣例輸入

5 1000
144 990
487 436
210 673
567 58
1056 897

樣例輸出

2099

思路:

01揹包模板,採用一維數組。

代碼:

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
int w[1000000],c[1000000];
int f[1000000*4];
int main()
{
    int n,m;
    cin>>n>>m;
    for(int i=1;i<=n;i++)
    {
        cin>>w[i]>>c[i];
    }
    for(int i=1;i<=n;i++)
    {
        for(int v=m;v>=w[i];v--)
        {
            if(f[v-w[i]]+c[i]>f[v])
            {
                f[v]=f[v-w[i]]+c[i];
            }
        }
    }
    cout<<f[m]<<endl;
    return 0;
}

--------------------------------------------------------------------------------------------------------------------------

#1043 : 完全揹包

時間限制:20000ms

單點時限:1000ms

內存限制:256MB

描述

且說之前的故事裏,小Hi和小Ho費勁心思終於拿到了茫茫多的獎券!而現在,終於到了小Ho領取獎勵的時刻了!

等等,這段故事爲何似曾相識?這就要從平行宇宙理論說起了………總而言之,在另一個宇宙中,小Ho面臨的問題發生了細微的變化!

小Ho現在手上有M張獎券,而獎品區有N種獎品,分別標號爲1到N,其中第i種獎品需要need(i)張獎券進行兌換,並且可以兌換無數次,爲了使得辛苦得到的獎券不白白浪費,小Ho給每件獎品都評了分,其中第i件獎品的評分值爲value(i),表示他對這件獎品的喜好值。現在他想知道,憑藉他手上的這些獎券,可以換到哪些獎品,使得這些獎品的喜好值之和能夠最大。

提示一: 切,不就是0~1變成了0~K麼

提示二:強迫症患者總是會將狀態轉移方程優化一遍又一遍

提示三:同樣不要忘了優化空間哦!

輸入

每個測試點(輸入文件)有且僅有一組測試數據。

每組測試數據的第一行爲兩個正整數N和M,表示獎品的種數,以及小Ho手中的獎券數。

接下來的n行描述每一行描述一種獎品,其中第i行爲兩個整數need(i)和value(i),意義如前文所述。

測試數據保證

對於100%的數據,N的值不超過500,M的值不超過10^5

對於100%的數據,need(i)不超過2*10^5, value(i)不超過10^3

輸出

對於每組測試數據,輸出一個整數Ans,表示小Ho可以獲得的總喜好值。

樣例輸入

5 1000
144 990
487 436
210 673
567 58
1056 897

樣例輸出

5940

 

思路:

完全揹包模板

代碼:

#include<iostream>
using namespace std;
int w[1000000*4],c[1000000*4];
int f[1000000*4];
int main()
{
    int n,m;
    cin>>n>>m;
    for(int i=1;i<=n;i++)
        cin>>w[i]>>c[i];

    for(int i=1;i<=n;i++)
    {
        for(int v=w[i];v<=m;v++)
        {
            if(f[v]<f[v-w[i]]+c[i])
                f[v]=f[v-w[i]]+c[i];
        }
    }
    cout<<f[m]<<endl;
    return 0;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章