codeforces 688E - The Values You Can Make 简单dp

Posted shuguangzw

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了codeforces 688E - The Values You Can Make 简单dp相关的知识,希望对你有一定的参考价值。

题意:一个数组a[i],你可以挑出若干个数(只能挑一次)加起来等于k,

        针对每一种方案,你可以选出这若干个数的子集来组合新数

        最后所有的方案能组合出多少种数

分析:一看数据范围n,k<=500

         那就是显而易见就是母函数那套了

         从1到n,dp[i][j],代表通过前i个元素和为i,能否组合出j

#include <cstdio>
#include <iostream>
#include <ctime>
#include <vector>
#include <cmath>
#include <map>
#include <set>
#include <stack>
#include <queue>
#include <algorithm>
#include <cstring>
using namespace std;
typedef long long LL;
const int N=1e5+5;
const int INF=0x3f3f3f3f;
const int mod=1e9+7;
int a[N],n,p;
int dp[505][505],tmp[505];
vector<int>ret;
int main(){
    scanf("%d%d",&n,&p);
    for(int i=1;i<=n;++i){
      scanf("%d",&a[i]);
    }
    sort(a+1,a+1+n);
    dp[0][0]=1;
    for(int i=1;i<=n;++i){
      for(int j=p;j>=a[i];--j){
        for(int k=0;k+a[i]<=p;++k)
        if(dp[j-a[i]][k])dp[j][k]=dp[j][k+a[i]]=1; 
      }
    }
    for(int i=0;i<=p;++i)
      if(dp[p][i])ret.push_back(i);
    printf("%d\\n",ret.size());
    for(int i=0;i<ret.size()-1;++i)
      printf("%d ",ret[i]);
    printf("%d\\n",ret[ret.size()-1]);
    return 0;
}
View Code

 

以上是关于codeforces 688E - The Values You Can Make 简单dp的主要内容,如果未能解决你的问题,请参考以下文章

codeforces 842C Ilya And The Tree (01背包+dfs)

E. The Values You Can Make 背包,同时DP

CodeForces 622B The Time

Educational Codeforces Round 7 F - The Sum of the k-th Powers 拉格朗日插值

CodeForces 625B War of the Corporations

CodeForces 625A Guest From the Past