玩具(toy)


題目

  

試題2:玩具(toy) 

源代碼:toy.cpp 

輸入文件:toy.in 

輸出文件:toy.out 

時間限制:1s 

空間限制:256MB 

題目描述 

商店正在出售小C最喜歡的系列玩具,在接下來的n周中,每周會出售其中的一款,同一款玩具不會重復出現。 

由於是小C最喜歡的系列,他希望盡可能多地購買這些玩具,但是同一款玩具小C只會購買一個。同時,小C的預算只有m元,因此他無法將每一款都納入囊中。此外,小C不能連續兩周都購買玩具,否則他會陷入愧疚。現在小C想知道,他最多可以買多少款不同的玩具呢? 

輸入說明

輸入文件共2行; 

第一行兩個正整數n和m,中間用一個空格隔開; 

第二行共n個正整數,第i個正整數表示第i周出售的玩具的價格。 

輸出說明

輸出文件只有一行,包含一個整數,表示小C最多能買多少款不同的玩具。

樣例輸入

3 8 

4 4 5 

樣例輸出

數據范圍

對於30%的數據,n≤10; 

對於60%的數據,n≤100,m≤1000; 

對於100%的數據,n≤1000,m≤1000000,單個玩具的價格≤1000。

分析

  首先,根據“同一款玩具小C只會購買一個”我們得知大體的做題方向是01背包的DP

  所以我們用f[i]記錄花i塊錢最多能購買到的玩具數量

  但是! 題目中說“不能連續兩周都購買玩具”,所以我們可以打標記避免連續兩周都購買玩具。

  粗略的分析完這些,我們就可以寫代碼了!

 

  可惜的是你會發現你無法開下一個n*m的數組去打標記(因為n≤1000,m≤1000000)。

  如何縮小一個數組的空間呢?

  要么是狀態壓縮,要么是滾動數組。

  而現在的情況用滾動數組會更簡單一點。

代碼

#include<iostream>
#include<cmath>
#include<algorithm>
#include<cstdlib>
#include<cstdio>
using namespace std;
int n,m,a[11001];
int f[1100001];//f[i]記錄花i塊錢最多能購買到的玩具數量
bool flag[1100001][3];//f[i][j]記錄f[i]在上周是否購買了玩具(j是用來滾動數組的)
int main()
{
    cin>>n>>m;
    for(int i=1;i<=n;i++) scanf("%d",&a[i]);
    int o1=1,o2=2;
    for(int i=1;i<=n;i++)
    {
        swap(o1,o2);//滾動一次flag數組
        for(int j=0;j<=m;j++) flag[j][o2]=0;
        for(int j=m;j>=a[i];j--)
        {
            if(f[j-a[i]]+1>f[j] && !flag[j-a[i]][o1])
            {
                flag[j][o2]=1;
                f[j]=f[j-a[i]]+1;
            }
        }
    }
    cout<<f[m];
    return 0;
}

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM