1. 程式人生 > >多重部分和問題(多重揹包+二進位制優化)

多重部分和問題(多重揹包+二進位制優化)

時間限制: 1 Sec  記憶體限制: 64 MB
提交: 18  解決: 14

題目描述

有n種不同大小的數字,每種各個。判斷是否可以從這些數字之中選出若干使它們的和恰好為K。

輸入

首先是一個正整數T(1<=T<=100)
接下來是T組資料
每組資料第一行是一個正整數n(1<=n<=100),表示有n種不同大小的數字
第二行是n個不同大小的正整數ai(1<=ai<=100000)
第三行是n個正整數mi(1<=mi<=100000),表示每種數字有mi個
第四行是一個正整數K(1<=K<=100000)

輸出

對於每組資料,如果能從這些數字中選出若干使它們的和恰好為K,則輸出“Yes”,否則輸出“No”,每個輸出單獨佔一行

樣例輸入

2 3 3 5 8 3 2 2 17 2 1 2 1 1 4

樣例輸出

Yes No
思路:有mi個啊ai,則可以把每個ai看成獨立的數,比如例子上有3個3,2個5,2個8,我們可以看成7個獨立的數,看看
把這7個數怎樣組合可以得到k,這就變成了01揹包問題。思想懂了就要優化了,想想依稀有100個數,沒個數也有100,
一共就有10000個數,這樣肯定會超時,所以用到了二進位制優化,比如有20個3,就可以把3 分成1,2,4,8,5個3 等。
然後20以內的數都可以用這幾個數表示。
100以內都可以用1,2,4,8,16,32,37個數來表示,

#include <stdio.h>
#include <string.h>
#include <algorithm>
int dp[100005];
int a[105],w[105];
int main()
{
	using namespace std;
	int t;
	scanf("%d",&t);
	int n;
	int k;
	int i,j,l;
	int ans;
	while(t--)
	{
		scanf("%d",&n);
		for(i=1; i <= n; i++)
		{
			scanf("%d",&a[i]);
		}
		for(i=1; i <= n; i++)
		{
			scanf("%d",&w[i]);
		}
		scanf("%d",&k);
		memset(dp,0,sizeof(dp));
		for(i=1; i<=n; i++)
		{
			if(dp[k]==k)
			{
				break;
			}
			if(a[i]*w[i] >= k)//如果它大於K,則在k範圍內可以看成這個數是無窮的 
			{
				for(j=a[i]; j <=k; j++)//所以j可以從下到大累加 
				{
					dp[j] = max(dp[j-a[i]]+a[i] , dp[j]);
				}
			}
			else
			{
				ans=1;
				while(w[i] >= ans)
				{
					for( j=k; j >= ans*a[i]; j--)
					{
						dp[j] = max(dp[j-ans*a[i]]+ans*a[i] , dp[j]);
					}
					w[i] -= ans;
					ans <<= 1;//相當於ans *= 2;但是比它快。 
				}
				for( j=k; j >= w[i]*a[i]; j--)
				{
					dp[j] = max(dp[j-w[i]*a[i]]+w[i]*a[i] , dp[j]);
				}
			}
		}
		if(dp[k]==k)
		{
			printf("Yes\n");
		}
		else
		{
			printf("No\n");
		}
	}
	return 0;
}




相關推薦

多重部分問題多重揹包+二進位制優化

時間限制: 1 Sec  記憶體限制: 64 MB提交: 18  解決: 14 題目描述 有n種不同大小的數字,每種各個。判斷是否可以從這些數字之中選出若干使它們的和恰好為K。 輸入

HDU-1059-Dividing多重揹包+二進位制優化

Problem DescriptionMarsha and Bill own a collection of marbles. They want to split the collection among themselves so that both receive an equal share of t

Cash Machine POJ 1276多重揹包——二進位制優化

題意:給你一個最大金額m,現在有n種類型的紙票,這些紙票的個數各不相同,問能夠用這些紙票再不超過m的前提下湊成最大的金額是多少? 題解:寫了01揹包直接暴力,結果T了,時間複雜度太高了,要跑外迴圈

不易POJ-1742 多重部分多重揹包可行性

題目大意:傳說中的男人八題,是男人就A這八題。有n種面額的硬幣,面額個數分別為A_i、C_i,求最多能搭配出幾種不超過m(1-m)的金額? 分析: ①首先來看看樸素的方法: bool dp[i]

約數神奇的數列優化

main urn sca 結果 using 思路 告訴 inline 數字 題目大意 求區間[x,y]中所有元素的因數和(x<=y) 思路 如果這道題太難了,來看看另一道簡單的題: 給你很多個數N,需要你算出這些數所有約數的和。(N的約數指能整除N的正整數),例如12

多重揹包二進位制優化wzk吃小雞腿

問題 B: WZK吃小雞腿(chicken) 時間限制: 1 Sec   記憶體限制: 128 MB 提交: 53   解決: 23 [ 提交][ 狀態][ 討論版

dp 多重揹包二進位制優化

在多重揹包的問題中,有時物品的件數會給的非常大,此時從1件到n件遍歷很容易超時,下面講一下二進位制優化的思路 答題思想為:把同種多件物體轉換為多種單件物體。 我們已經知道,1、2、4、8 、16 、 32……2^n  可以組成從1到2^(n+1)-1中的任何數

多重揹包二進位制優化POJ1276

主要是記錄一下對於揹包問題的二進位制優化方法1.多重揹包使用二進位制優化後轉化為01揹包問題#include <iostream> #include <cstdio> #incl

甜點(多重揹包+二進位制優化)

描述 小z準備舉辦一個比賽。他需要提供一些甜點給參賽者來補充能量。每種甜品有一定的能量ti和大小ui,且每種甜點最多有vi個。 小z準備用箱子來包裝甜點。箱子可以容納一定體積的甜點且需要一定的費用。小z有一種魔法,可以將一個甜點分成多份裝在箱子裡,最後再合在一起(但合成之後必須是完整的一個)

多重揹包+二進位制優化】ACM-ICPC 2018 焦作賽區網路預賽 - K. Transport Ship

題目連結<https://nanti.jisuanke.com/t/31720> 題意: 給出若干個船,每個船都有的容量,和的數量。有Q次詢問,給出一定體積的貨物,問你恰好裝滿的方案數量。 題解: 很明顯的多重揹包,但是要加上二進位制優化。 所謂二進位制優

多重揹包二進位制優化分析

列出一個模板供參考: #include<bits/stdc++.h> #include<time.h> #define INF 0x3f3f3f3f using namespace std; #define N 1000 #define M 100000000 int

Cash Machine POJ - 1276 多重揹包二進位制優化

題意:多重揹包模型  n種物品 每個m個  問揹包容量下最多拿多少 這裡要用二進位制優化不然會超時   1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4

Dividing POJ - 1014 多重揹包二進位制優化

多重揹包模型  寫的時候漏了一個等號找了半天 i<<=1 !!!!!!     1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 usin

多重部分問題動態規劃DP

注:文章內容源自《挑戰程式設計競賽》(第二版) 原題 多重部分和問題 有n種不同大小的數字ai,每種各mi個。判斷是否可以從這些數字之中選出若干使它們的和恰好為K。 1<=n<=100 1<=ai,mi<=100000 1<=K<=100

DP 經典問題多重部分問題

問題描述: 有n種不同大小的數字ai,每種各mi個,判斷是否可以從這些數字之中選出若干使它們的和恰好為K。(1 <=n <= 100 , 1 <= ai,mi <=100000 , 1 <= K <= 100000) 輸入

063_多重部分問題DP

     多重部分和問題:給定一組數,並且給定期中每個數出現的次數,試問是否存在這樣的組合,使其和為一個值K?(某個數可以取多次,但不能超過其次數)      如:a={3,5,8}             m={3,2,2}             K=17;      

POJ1742 dp 多重部分問題

題意:要買一個m價錢的東西,現在有一些硬幣,每種硬幣個數和價值不同,求能用這些硬幣在1~m的價格中買到幾種東西。 思路:以dp[j]中j為價格為j的物品,dp[j]的值為第i種硬幣的個數,以此來把

POJ 1742 Coins ( 經典多重部分問題 && DP || 多重背包 )

count ... mes opened view display 是什麽 [] sizeof 題意 : 有 n 種面額的硬幣,給出各種面額硬幣的數量和和面額數,求最多能搭配出幾種不超過 m 的金額? 分析 : 這題可用多重背包來解,但這裏不討論這種做法。 如果之前有

HDU 1059多重背包加二進制優化

panel pos test them NPU contest chm equal tel http://acm.hdu.edu.cn/showproblem.php?pid=1059 Dividing Time Limit: 2000/1000 MS (Java/Othe

POJ1742 coins 動態規劃之多重部分問題

變形 價值 span 維數 text 推出 遞推 pro cal 原題鏈接:http://poj.org/problem?id=1742 題目大意:tony現在有n種硬幣,第i種硬幣的面值為A[i],數量為C[i]。現在tony要使用這些硬幣去買一塊價格不超過m的表。他希望