hdu3535AreYouBusy(分組揹包問題)
常見的有三種,
一,每組最多取一個,
一維陣列的虛擬碼
for 所有的組k
for v = V to 0
for 所有的i屬於組k
f[v] = max{f[v], f[v -c[i]] + w[i]}
注意順序不能寫反,因為要限制每組最多取一個
二,每組任意取
既然上面的順序是限制每組最多取一個,那調換一下順序即可,其實就是01揹包。
一維陣列的虛擬碼
for 所有的組k
for 所有的i屬於組k
for v = V to 0
f[v] = max{f[v], f[v -c[i]] + w[i]}
三,每組至少取一個
沒見過一維的虛擬碼,
dp[ki}[i}表示當前不選,dp[ki-1}[i-b[ki}}+c[ki}表示這是第一個選,
dp[ki}[i-b[ki}}+c[ki}表示再在這一組中選。
初始化時記得ki==0,賦值0,
其他賦值-inf
dp[ki}[i}=max(dp[ki}[i},dp[ki-1}[i-b[ki}}+c[ki},dp[ki}[i-b[ki}}+c[ki})
//分開寫時要注意順序!!!
下面這道題是這三種的綜合,由於第三種情況要用二維寫,所以就都用二維寫。
if(type==0)
for(int i=0;i<=T;i++) dp[ni][i]=-inf;
else
for(int i=0;i<=T;i++) dp[ni][i]=dp[ni-1][i];
上面程式碼是將狀態從上一個組傳遞到當前組。
#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <stdlib.h>
#include <stack>
#include <vector>
#include <string.h>
#include <queue>
#define msc(X) memset(X,-1,sizeof(X))
#define ms(X) memset(X,0,sizeof(X))
typedef long long LL;
using namespace std;
const int inf=0x7fffffff;
int dp[102][102];
int main(int argc, char const *argv[])
{
int N,T;
while(scanf ("%d %d",&N,&T)==2){
ms(dp);
for(int ni=1;ni<=N;ni++)
{
int num,type;
scanf("%d %d",&num,&type);
if(type==0) for(int i=0;i<=T;i++) dp[ni][i]=-inf;
else for(int i=0;i<=T;i++) dp[ni][i]=dp[ni-1][i];
if(type==0){//至少選一個
while(num--){
int c,g;
scanf("%d %d",&c,&g);
for(int i=T;i>=c;i--)
{
dp[ni][i]=max(dp[ni][i],dp[ni][i-c]+g);
dp[ni][i]=max(dp[ni][i],dp[ni-1][i-c]+g);
}
}
}
else if(type==1){//至多選一個
while(num--){
int c,g;
scanf("%d %d",&c,&g);
for(int i=T;i>=c;i--)
{
dp[ni][i]=max(dp[ni][i],dp[ni-1][i]);
dp[ni][i]=max(dp[ni][i],dp[ni-1][i-c]+g);
}
}
}
else{//隨意
while(num--){
int c,g;
scanf("%d %d",&c,&g);
for(int i=T;i>=c;i--)
{
dp[ni][i]=max(dp[ni][i],dp[ni-1][i]);
dp[ni][i]=max(dp[ni][i],dp[ni][i-c]+g);
dp[ni][i]=max(dp[ni][i],dp[ni-1][i-c]+g);
}
}
}
}
if(dp[N][T]<0) puts("-1");
else printf("%d\n",dp[N][T] );
}
return 0;
}
相關推薦
hdu3535AreYouBusy(分組揹包問題)
常見的有三種, 一,每組最多取一個, 一維陣列的虛擬碼 for 所有的組k for v = V to 0 for 所有的i屬於組k f[v] =
p1277 競賽真理(分組揹包)
題目 描述 Description 小甜甜在經歷了無數次學科競賽的失敗以後,得到了一個真理:做一題就要對一題!但是要完全正確地做對一題是要花很多時間(包括除錯時間),而競賽的時間有限。所以開始做題之前最好先認真審題,估計一下每一題如果要完全正確地做出來所需要的時間,然後選擇一些有把
ACboy needs your help (分組揹包)
ACboy has N courses this term, and he plans to spend at most M days on study.Of course,the profit he will gain from different course depending on the
揹包問題(分組揹包)
Just to remind, girls in Arpa's land are really nice. Mehrdad wants to invite some Hoses to the palace for a dancing party. Each Hos has some weight wi
946D Timetable(分組揹包)
Timetabletime limit per test2 secondsmemory limit per test256 megabytesinputstandard inputoutputstandard outputIvan is a student at Berlan
ZOJ3769-Diablo III(分組揹包)
題意:有兩個屬性:攻擊和防禦,擊敗對手,你需要儘可能大的攻擊和大於等於m的防禦,接下來n行n個裝置,一共13種裝備,每種裝備都有攻擊力和防禦值,每種裝備只允許選擇一個,13種裝備裡如果選擇了雙手裝備,就不能選擇武器和護盾,Finger可以最多同時存在兩個,問你能獲得的最大攻擊。
ZOJ 3769 (分組揹包)
分組揹包 分組問題在實現的時候就想分層一樣,每一種商品就是一層 這一層基於上一層計算 題意: 13種裝備(每種可能會有多件),每件裝備有兩個屬性:傷害,韌性。現在一個人想裝備這些裝備,目
【題解】洛谷P1273 有線電視網(樹上分組揹包)
次元傳送門:洛谷P1273 思路 一開始想的是普通樹形DP 但是好像實現不大好 觀摩了一下題解 是樹上分組揹包 設f[i][j]為以i為根的子樹中取j個客戶得到的總價值 我們可以以i為根有j組 在每一組中分別又取1個,2個,3個......n個客戶 化為揹包思想即 j為一共有j組 揹包容量為每
51Nod1007 正整數分組(01揹包)
這道題思路就是算出陣列總和,在陣列中找到和最接近陣列總和一半的一些數。 可以用01揹包解決這道題,dp[i][j]表示在陣列前i項中最接近j的最大值。 狀態轉移方程為:dp[i][j]=max(dp[i-1][j],dp[i-1][j-a[i]]+a[i]); #include<
Codeforces Round #383 (Div. 2)D-(並查集&分組揹包)|(搜尋&01揹包)
傳送門 分組揹包模板題。 用並查集搞一搞一齊的關係就好。 然後就是分組揹包的模板了,注意,在分組的時候,把i組所有和加起來 這一個虛擬的物品分到 i組裡,而不能獨立分組,不然會造成某一個模特
codeforces 946 D Timetable(預處理+分組揹包)
思路:先預處理出每天去掉x節課能少去學校的時間,然後就變成了n組每組挑一個,容量大小為K的分組揹包了。#include <cstdio> #include <cstdlib> #
【codeforces 946D】Timetable(預處理+分組揹包)
=-=以前揹包沒學好。。。居然是第一次做分組揹包的題,咳咳 不過這題比較厲害的是它的預處理。。。心態崩了,為什麼有的時候一個回車會往下走這麼多行想刪回車,一下子就刪了一段,還不知道在哪撤回
動態規劃:HDU1712-ACboy needs your help(分組揹包問題)
The input consists of multiple data sets. A data set starts with a line containing two positive integers N and M, N is the number of courses, M is the day
codeforces 946d D. Timetable(預處理+ 分組揹包)
D. Timetabletime limit per test2 secondsmemory limit per test256 megabytesinputstandard inputoutputstandard outputIvan is a student at Berland State Univer
HDU4281 Judges' response(狀態壓縮+01揹包+分組揹包)經典
Judges' response Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 565 Accepted
採藥-動態規劃(01揹包)
採用一維陣列進行優化 #include<cstdio> #include<algorithm> using namespace std; int w[105], v[105]; int dp[1005]; int main() { int m, n; sca
HDU 2191 - 悼念512汶川大地震遇難同胞——珍惜現在,感恩生活 (多重揹包)
題目 急!災區的食物依然短缺! 為了挽救災區同胞的生命,心繫災區同胞的CK準備自己採購一些糧食支援災區,現在假設CK一共有資金n元,而市場有m種大米,每種大米都是袋裝產品,其價格不等,並且只能整袋購買。 請問:CK能用有限的資金最多能採購多少公斤糧食呢? Input 輸入資料首先
B - Bone Collector (01揹包)
題目: 塗奧最近迷上了吃雞,房間有n個配件,每個配件有c(c<=1e3)的重量和v(v<=1e3)的價值,哇,塗奧撿了一個2級包,容量為s,所以塗奧最多當多肥的快遞員呢? Input 輸入的第一行是T, 表示有一共要打T場比賽. 每組資料由三行組成. 第1行包含兩個整數
和為K的組合(01揹包)
給出N個正整陣列成的陣列A,求能否從中選出若干個,使他們的和為K。如果可以,輸出:“Yes”,否則輸出"No"。 Input 第1行:2個數N, K, N為陣列的長度, K為需要判斷的和(2 <= N <= 20,1 <= K <= 10^9) 第2 - N + 1行
HDU 2602 Bone Collector(01揹包)
Bone Collector Many years ago , in Teddy’s hometown there was a man who was called “Bone Collector”. This man like to collect varies of bones , s