码迷,mamicode.com
首页 > 其他好文 > 详细

CodeForces - 687C The Values You Can Make (多背包解法)

时间:2020-07-08 01:41:40      阅读:87      评论:0      收藏:0      [点我收藏+]

标签:value   example   turn   判断   题目   clu   相加   存在   input   

题目链接:https://codeforces.com/problemset/problem/687/C

题目大意:给你n个数,然后让这些数相加组合,然后在这些组合的数里可以再相加组合搞出给定 k,输出这些组合的数。

Examples

Input
6 18
5 6 1 10 12 2
Output
16
0 1 2 3 5 6 7 8 10 11 12 13 15 16 17 18
Input
3 50
25 25 50
Output
3
0 25 50

emmm,实际上我们可以看到的是这些数是成对出现的,那么我们只需要对每对数进行搜寻判断就好了,如果$i,k-i$可以同时由上面的数组合而成,那么我们就可以肯定$i,k-i$是存在的,可以输出的。那么怎么判断一对数能否同时由上面的数组合而成呢?应该很容易想到背包,之前讲过的多背包问题也就在这里再一次的运用上了,定义背包状态$dp[i][j]$表示$i,j$容量的时候最大能够取得的价值,那么如果$dp[i][k-i]==k$也就是两个背包刚好都装满了。于是。。。。此题结束。。。

以下是AC代码:

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;

const int mac=550;

int a[mac],ans[mac];
int dp[mac][mac];

int main()
{
    int n,m;
    scanf ("%d%d",&n,&m);
    for (int i=1; i<=n; i++)
        scanf ("%d",&a[i]);
    for (int i=1; i<=n; i++)
        for (int j=m; j>=0; j--)
            for (int k=m; k>=0; k--){
                if (j-a[i]>=0) dp[j][k]=max(dp[j][k],dp[j-a[i]][k]+a[i]);
                if (k-a[i]>=0) dp[j][k]=max(dp[j][k],dp[j][k-a[i]]+a[i]);
            }
    int cnt=0;
    for (int i=0; i<=(m-1)/2; i++){
        if (dp[i][m-i]==m) ans[++cnt]=i,ans[++cnt]=m-i;
    }
    if (!(m&1) && dp[m/2][m/2]==m) ans[++cnt]=m/2;  
    sort(ans+1,ans+1+cnt);
    printf("%d\n",cnt );
    for (int i=1; i<=cnt; i++)
        printf("%d%c",ans[i],i==cnt?\n: );
    return 0;
}

 

CodeForces - 687C The Values You Can Make (多背包解法)

标签:value   example   turn   判断   题目   clu   相加   存在   input   

原文地址:https://www.cnblogs.com/lonely-wind-/p/13264361.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!