您的位置:首页 > 其它

4515: 又见背包

2017-07-15 20:09 197 查看
4515: 又见背包

源网址

https://vjudge.net/problem/SCU-4515

Time Limit: 500 MSMemory Limit: 62768 K

描述

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

输入

输入包含多组数据。第一行为一个整数,代表数据组数,对于每组数据:

第一行输入n,k ()

第二行n个数,代表~.

第三行n个数,代表~.

输出

每组数据输出一行

满足条件能使得和恰好为k,输出”yes”.

否则输出”no”.

样例输入

1

2 2

1 1

2 2

样例输出

yes

这是动态规划的一种经典题型

这是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);
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息