zoukankan      html  css  js  c++  java
  • 【CF-687C】The Values You Can Make 01背包变形

    C. The Values You Can Make

    题意

    给出n,k,以及n个数字,选取若干个数字组成k,在这若干个数字中选择一个子集,

    问这个子集的和,可能的值有多少个。

    题解

    刚开始写的是01背包向前递推,然后写凉了。

    是01背包的变形。

    (dp[i][j][k])表示在前i个数字中选取若干个数字,组成j的同时组成k是否可行。

    (dp[i][j][k]=max(dp[i-1][j-a[i]][l-a[i]],dp[i-1][j-a[i][l]]);)

    最后统计(dp[n][k][i]==1)的个数。

    代码

    #include<bits/stdc++.h>
    #define pb push_back
    typedef long long ll;
    using namespace std;
    const int inf = 0x3f3f3f3f;
    const int mod = 1e9+7;
    const int N = 5e3+10;
    
    int arr[N],dp[N][N];
    int main()
    {
        int n,k;
        scanf("%d%d",&n,&k);
        for(int i=1; i<=n; i++)
            scanf("%d",&arr[i]);
        dp[0][0]=1;
        for(int i=1;i<=n;i++)
        {
            for(int j=k;j>=arr[i];j--)
            {
                for(int l=k;l>=0;l--)
                {
                    dp[j][l]=max(dp[j][l],dp[j-arr[i]][l]);
                    if(l>=arr[i]) dp[j][l]=max(dp[j][l],dp[j-arr[i]][l-arr[i]]);
                }
            }
        }
        int ans=0;
        for(int i=0;i<=k;i++)
        {
            if(dp[k][i])
                ans++;
        }
        printf("%d
    ",ans);
        for(int i=0;i<=k;i++)
        {
            if(dp[k][i])
                printf("%d ",i);
        }
        printf("
    ");
        return 0;
    }
    
  • 相关阅读:
    互联网协议
    TCP/IP协议三次握手_四次挥手
    nginx重定向rewrite
    创建第一个django工程
    Anaconda-用conda创建python虚拟环境
    数组
    StringBuilder
    杨辉三角
    数据类型和变量
    .net框架中的一些接口
  • 原文地址:https://www.cnblogs.com/valk3/p/12943828.html
Copyright © 2011-2022 走看看