1. 程式人生 > >混合背包問題(櫻花)

混合背包問題(櫻花)

AI 類型 esp space 背景 輸出 如何 tro IV

題目背景

《愛與愁的故事第四彈·plant》第一章。

題目描述

愛與愁大神後院裏種了n棵櫻花樹,每棵都有美學值Ci。愛與愁大神在每天上學前都會來賞花。愛與愁大神可是生物學霸,他懂得如何欣賞櫻花:一種櫻花樹看一遍過,一種櫻花樹最多看Ai遍,一種櫻花樹可以看無數遍。但是看每棵櫻花樹都有一定的時間Ti。愛與愁大神離去上學的時間只剩下一小會兒了。求解看哪幾棵櫻花樹能使美學值最高且愛與愁大神能準時(或提早)去上學。

輸入輸出格式

輸入格式:

共n+1行:

第1行:三個數:現在時間Ts(幾點:幾分),去上學的時間Te(幾點:幾分),愛與愁大神院子裏有幾棵櫻花樹n。

第2行~第n+1行:每行三個數:看完第i棵樹的耗費時間Ti,第i棵樹的美學值Ci,看第i棵樹的次數Pi(Pi=0表示無數次,Pi是其他數字表示最多可看的次數Pi)。

輸出格式:

只有一個整數,表示最大美學值。

題目背景

《愛與愁的故事第四彈·plant》第一章。

題目描述

愛與愁大神後院裏種了n棵櫻花樹,每棵都有美學值Ci。愛與愁大神在每天上學前都會來賞花。愛與愁大神可是生物學霸,他懂得如何欣賞櫻花:一種櫻花樹看一遍過,一種櫻花樹最多看Ai遍,一種櫻花樹可以看無數遍。但是看每棵櫻花樹都有一定的時間Ti。愛與愁大神離去上學的時間只剩下一小會兒了。求解看哪幾棵櫻花樹能使美學值最高且愛與愁大神能準時(或提早)去上學。

輸入輸出格式

輸入格式:

共n+1行:

第1行:三個數:現在時間Ts(幾點:幾分),去上學的時間Te(幾點:幾分),愛與愁大神院子裏有幾棵櫻花樹n。

第2行~第n+1行:每行三個數:看完第i棵樹的耗費時間Ti,第i棵樹的美學值Ci,看第i棵樹的次數Pi(Pi=0表示無數次,Pi是其他數字表示最多可看的次數Pi)。

輸入輸出樣例

輸入樣例#1: 復制
6:50 7:00 3
2 1 0
3 3 1
4 5 4
輸出樣例#1: 復制
11

說明

100%數據:Te-Ts ≤ 1000,n ≤ 10000

樣例解釋:賞第一棵櫻花樹一次,賞第三棵櫻花樹2次

解析:其實就是一道普通的多重背包和完全背包的組合。我覺得考察背包題應該進行多種小背包類型的組合。

註意:多重背包不用乘數量,

for(int k=1;k<=num[i];k++)
for(int j=v;j>=w[i]*k;--j)
dp[j]=max(dp[j], dp[j-w[i]*k]+c[i]*k);是錯誤的

正確的。————————————————————

for(int k=1;k<=num[i];k++)
for(int j=v;j>=w[i]*k;--j)
dp[j]=max(dp[j], dp[j-w[i]]+c[i]);

————————————————————————好吧,也暴露了自己的弱點。加油改正。

代碼如下:

#include<iostream>
#include<stdio.h>
using namespace std;
int dp[10001], w[10001],c[10001],num[10001];
int main()
{
int h1,m1,h2,m2,n;
scanf("%d:%d%d:%d%d", &h1,&m1,&h2,&m2,&n);
int v=h2*60+m2-(h1*60+m1);
for(int i=1;i<=n;i++)
cin>>w[i]>>c[i]>>num[i];
for(int i=1;i<=n;i++)
{
if(num[i]==0)
{
for(int j=w[i];j<=v;++j)
dp[j]=max(dp[j], dp[j-w[i]]+c[i]);
}
else
{
for(int k=1;k<=num[i];k++)
for(int j=v;j>=w[i]*k;--j)
dp[j]=max(dp[j], dp[j-w[i]]+c[i]);
}
}
cout<<dp[v]<<endl;
return 0;
}

混合背包問題(櫻花)