多重部分和问题

  题意:有n种不同大小的数字ai 每种各mi个 判断是否可以从这些数字之中选出若干个使它们的和恰好为K

朴素做法  为三次方

有一种 nK的做法:

dp[i][j]表示 前i个数  凑到j最多剩下多少个mi

dp[i][j]

1.如果dp[i][j]>=0 那么肯定为mi

2.如果 j<ai or  dp[i][j-ai]]<=0 那么为-1  表示无解

3. 其他情况  dp[i][j-ai]]-1;

#include<bits/stdc++.h>
using namespace std;
//input by bxd
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define repp(i,a,b) for(int i=(a);i>=(b);--i)
#define RI(n) scanf("%d",&(n))
#define RII(n,m) scanf("%d%d",&n,&m)
#define RIII(n,m,k) scanf("%d%d%d",&n,&m,&k)
#define RS(s) scanf("%s",s);
#define ll long long
#define pb push_back
#define CLR(A,v)  memset(A,v,sizeof A)
//////////////////////////////////
#define inf 0x3f3f3f3f
const int N=100+5;
int n,m,dp[N];
int a[N],m[N],K;
int main()
{
    RI(n,K);
    rep(i,1,n)RI(a[i]);
    rep(i,1,n)RI(m[i]);
    
    CLR(dp,-1);
    dp[0]=0;
    rep(i,1,n)
    rep(j,0,K)
    if(dp[j]>=0){dp[j]=m[i];}
    else if(j<a[i]||dp[j-a[i]]<=0){dp[j]=-1;}
    dp[j]=dp[j-a[i]]-1;
    
    if(dp[K]>=0)printf("Yes
");
    else printf("No
");
    
    return 0;
}
View Code
原文地址:https://www.cnblogs.com/bxd123/p/10913559.html