• (01背包)输出方案数


    题目:

    老司机wbt又要开车了,焊死车门禁止下车,wbt现在在车内提供了n张电竞死歌wpm的CD唱片,已知wbt开车的时间是n分钟,你该如何去选择唱片去消磨这无聊的时间呢

    假设:

    • CD数量不超过20张
    • 没有一张CD唱片超过 N 分钟
    • 每张唱片只能听一次
    • 唱片的播放长度为整数
    • N 也是整数

    我们需要找到最能消磨时间的唱片数量,并按使用顺序输出答案(必须是听完唱片,不能有唱片没听完却到了下车时间的情况发生)

    Input

    多组输入

    每行输入第一个数字N, 代表总时间,第二个数字 M 代表有 M 张唱片,后面紧跟 M 个数字,代表每张唱片的时长 例如样例一: N=5, M=3, 第一张唱片为 1 分钟, 第二张唱片 3 分钟, 第三张 4 分钟

    所有数据均满足以下条件:

    N≤10000
    M≤20

    Output

    输出所有唱片的时长和总时长,具体输出格式见样例

    Sample Input

    5 3 1 3 4
    10 4 9 8 4 2
    20 4 10 5 7 4
    90 8 10 23 1 2 3 4 5 7
    45 8 4 10 44 43 12 9 8 2

    Sample Output

    1 4 sum:5
    8 2 sum:10
    10 5 4 sum:19
    10 23 1 2 3 4 5 7 sum:55
    4 10 12 9 8 2 sum:45


    #pragma GCC optimize(1)
    #pragma GCC optimize(2)
    #pragma GCC optimize(3,"Ofast","inline")
    #include<cstring>
    #include<cstdio>
    #include<iostream>
    #include<queue> 
    #include<algorithm>
    using namespace std;
    typedef long long ll;
    template <typename Tp>
    void read(Tp &x){//read(n);
        x=0;char ch=1;int fh;
        while(ch!='-'&&(ch>'9'||ch<'0')){
            ch=getchar();
        }
        if(ch=='-'){
            fh=-1;ch=getchar();
        }else fh=1;
        while(ch>='0'&&ch<='9'){
            x=(x<<1)+(x<<3)+ch-'0';ch=getchar();
        }
        x*=fh;
    }
    inline char read1()//字符串读入挂
    {
        register char ch=getchar();
        while(ch<'A'||ch>'M')ch=getchar();
        return ch; 
    }
    const int maxn=1e3+100; 
    int a[maxn];
    int dp[maxn][maxn];
    int b[maxn]; 
    int main(){
        int n,m;
        while(cin>>m){
            cin>>n;
            memset(dp,0,sizeof(dp));
            for(int i=1;i<=n;i++){
                cin>>a[i];
            }
            for(int i=1;i<=n;i++){
                for(int j=0;j<=m;j++){
                    dp[i][j]=dp[i-1][j];
                    if(j>=a[i]){
                        dp[i][j]=max(dp[i][j],dp[i-1][j-a[i]]+a[i]);
                    }
                }
            }
            int p=dp[n][m];
            int cnt=0;
            int sum=p;
            for(int i=n;i>=1;i--){
                if(dp[i][sum]==(dp[i-1][sum-a[i]]+a[i])){
                    sum-=a[i];
                    b[++cnt]=a[i];
                }
            }
            for(int i=cnt;i>=1;i--){
                cout<<b[i]<<" ";
            }
            printf("sum:%d
    ",p);
        }
    } 
  • 相关阅读:
    Nulls first和nulls last
    json.parse()和json.stringify()
    将单个的.java文件通过javac编辑为.class文件
    看别人项目思路:
    我想成为怎样的人?
    装逼语录:
    Uncompressing Linux... done, booting the kernel
    linux 内核模块最小环境编译
    select 定时器
    mount
  • 原文地址:https://www.cnblogs.com/lipu123/p/13775973.html
Copyright © 2020-2023  润新知