4515: 又见背包

4515: 又见背包

描述

有n种大小不同的数字 ai a i ,每种 mi m i 个,判断是否可以从这些数字中选出若干使它们的和恰好为k。 输入

输入包含多组数据。第一行为一个整数,代表数据组数,对于每组数据: 第一行输入n,k 第二行n个数,代表~. 第三行n个数,代表~.
输出

每组数据输出一行 满足条件能使得和恰好为k,输出”yes”. 否则输出”no”.

样例输入

1 2 2 1 1 2 2
样例输出

yes

这是动态规划的一种经典题型
这是matrix67大神的背包九讲的一种
这是matrix67大神的背包九讲的一种

#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
#define   MAX           105
#define   MAXN          100005
#define   mem(x,v)      memset(x,v,sizeof(x))
int a[MAX];
int m[MAX];
int dp[MAXN];
int main() {
    int t;
    cin >> t;
    while (t--) {
        int n, k;
        cin >> n >> k;
        for (int i = 1; i <= n; i++) scanf("%d", &a[i]);
        for (int i = 1; i <= n; i++) scanf("%d", &m[i]);
        mem(dp, -1);
        dp[0] = 0;
        for(int i=1;i<=n;i++){
            for(int j=0;j<=k;j++){
                if(dp[j]>=0) dp[j]=m[i];
                else if(j<a[i]||dp[j-a[i]]<=0) dp[j]=-1;
                else{
                    dp[j]=max(dp[j],dp[j-a[i]]-1);
                }//这是从一个博客看到的
            }
        }
        if (dp[k] >= 0) printf("yes\n");
        else printf("no\n");
    }
    return 0;
}
[Miracle_ma的专栏](http://blog.csdn.net/miracle_ma/article/details/51497619)

其中关键位置可以改为

for (int i = 1; i <= n; i++)
 {
   for (int j = 0; j <= k; j++) 
   {
     if (dp[j] >= 0) dp[j] = m[i];
     else if (j>=a[i] && dp[j - a[i]] > 0) 
          {
         dp[j] = max(dp[j], dp[j - a[i]] - 1);
                }
            }
        }
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值