您的位置:首页 > 其它

多重部分和二进制优化

2016-09-10 15:59 211 查看
多重部分和问题

题目描述

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

限制条件

1<=n<=100

1<=ai,mi<=100000

1<=k<=100000

输入

多组数据。

第一行n。第二行不同的数字ai.第三行对应数字拥有的个数

输出

能挑选若干恰好和为K则输出“Yes”,反之输出“No”.

样例输入

1

3

3 5 8

3 2 2

17

样例输出

Yes

#include <stdio.h>

#include <string.h>

int dp[100005];

int a[105];

int m[105];

int main()

{
int t, i, j, z, n, k, ans;
scanf("%d", &t);
while(t--)
{
scanf("%d", &n);
for(i = 0; i < n; i++)
scanf("%d", &a[i]); 
for(i = 0; i < n; i++)
scanf("%d", &m[i]); 
scanf("%d", &k);
memset(dp, -0x3f, sizeof(dp));
dp[0] = 0;
for(i = 0; i < n; i++)
{
if(m[i] * a[i] >= k)
{
for(j = a[i]; j <= k; j++)
dp[j] = dp[j] > dp[j - a[i]] + a[i] ? dp[j] : dp[j - a[i]] + a[i];
}
else
{
ans = 1;
while(m[i] - ans >= 0)
{
for(j = k; j >= ans * a[i]; j--)
dp[j] = dp[j] > dp[j - ans * a[i]] + ans * a[i] ? dp[j] : dp[j - ans * a[i]] + ans * a[i];
m[i] -= ans;
ans <<= 1; 
}
if(m[i] > 0)
{
for(j = k; j >= m[i] * a[i]; j--)
dp[j] = dp[j] > dp[j - m[i] * a[i]] + m[i] * a[i] ? dp[j] : dp[j - m[i] * a[i]] + m[i] * a[i];
}
}
}
if(dp[k] == k)
printf("Yes\n");
else
printf("No\n");
}
return 0;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: