描述
從前有2只狗,大的叫大狗,小的叫小狗,它們2個合起來就是狗兒們,使用英語的人把它們寫作Girlman,傳來傳去,到最後大家決定叫它們格爾曼。它們的叫聲很特別,但是它們十分吝嗇它們的叫聲,你爲了聽到它們的叫聲,決定買狗餅乾送給它們喫,不同種類的餅乾能讓它們叫的次數不一樣,同一塊餅乾對於大小格爾曼的效果也不一樣。它們很貪婪,如果你只給其中一隻格爾曼喫狗餅乾或者給兩隻格爾曼喫的不一樣,有一隻就會不高興,因此你買狗餅乾的時候總要兩塊兩塊地買,而且現在每類餅乾也只有2塊(想要多的也沒得)。現在不是流行節約型社會嗎?因此你也不能浪費,你要求的是在滿足你要聽格爾曼叫聲次數要求的情況(兩隻格爾曼實際叫的次數都不小於你的要求即可)下的最小花費是多少。
格式
輸入格式
輸入文件的第一行爲3個整數n、s、b,分別表示狗餅乾的類數、你想聽到的小格爾曼的叫聲次數和大格爾曼的叫聲次數,接下來有n行,第i+1行有3個整數si、bi、ci,分別表示第i類狗餅乾能讓小格爾曼叫的次數、能讓大格爾曼叫的次數和該類餅乾的單價。
30%的數據滿足1<=n<=30;
100%的數據滿足1<=n<=1000、1<=s,b<=50、0<=si ,bi ,ci <=2147483647。
輸出格式
輸出文件只有一個整數,爲滿足你的要求情況下的最小花費。
限制
1 second
來源
Conan From HNSDFZ
覺得這個題很好啊設dp[i][j]爲讓小格爾曼叫i次,大格爾曼叫j次需要的最小花費詳細題解請看註釋……
代碼:
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define maxn (4000 + 20)
#define inf 0x3f3f3f3f
#define pi acos(-1.0)
using namespace std;
typedef long long int LLI;
LLI sma[maxn],big[maxn],pri[maxn];
LLI dp[maxn][maxn];
int main() {
// freopen("in.txt","r",stdin);
// freopen("out.txt","w",stdout);
LLI n,s,b;
scanf("%lld%lld%lld",&n,&s,&b);
memset(dp,-1,sizeof(dp));/**用-1表示目前狀態沒有達到**/
for(int i = 1;i <= n;i ++){
scanf("%lld%lld%lld",&sma[i],&big[i],&pri[i]);
}
dp[0][0] = 0;
for(int i = 1;i <= n;i ++){
for(int j = s;j >= 0;j --){
for(int k = b;k >= 0;k --){
/**如果當前的狀態不存在,那麼不可能推出下一個狀態**/
if(dp[j][k] == -1) continue;
/**因爲不限制超出叫聲多少,只要>=要求的叫聲即可,而且dp[s][b]不用繼續向下推
//所以用dp[s][b]存所有的合法的答案,dp[s][b]=dp[x][y](x>s,y>b)*/
LLI x = min(j + sma[i],s);
LLI y = min(k + big[i],b);
if(dp[x][y] == -1) dp[x][y] = dp[j][k] + pri[i];
else dp[x][y] = min(dp[x][y],dp[j][k] + pri[i]);
}
}
}
printf("%lld\n",dp[s][b] * 2);
return 0;
}