您的位置:首页 > 其它

Vijos P1428 贪婪格尔曼

2016-09-13 21:17 281 查看
P1428贪婪格尔曼
Accepted


描述

从前有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

样例输入1[复制]

5 5 10
1 2 5
2 4 10
3 7 8
1 11 36
6 0 18


样例输出1[复制]

36



限制

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;
}


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