【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\n",ans);
    for(int i=0;i<=k;i++)
    {
        if(dp[k][i])
            printf("%d ",i);
    }
    printf("\n");
    return 0;
}

原文链接: https://www.cnblogs.com/valk3/p/12943828.html

欢迎关注

微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍;

也有高质量的技术群,里面有嵌入式、搜广推等BAT大佬

    【CF-687C】The Values You Can Make 01背包变形

原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/350406

非原创文章文中已经注明原地址,如有侵权,联系删除

关注公众号【高性能架构探索】,第一时间获取最新文章

转载文章受原作者版权保护。转载请注明原作者出处!

(0)
上一篇 2023年3月2日 上午6:18
下一篇 2023年3月2日 上午6:18

相关推荐