一道dp

it2022-05-05  209

链接:https://ac.nowcoder.com/acm/contest/321/L来源:牛客网

题目描述

鸡尾酒喜欢罐子,有一天他到了一个罐子专卖店,他决定买好多好多罐子回家。但是专卖店快关门了,鸡尾酒必须尽快选购,他决定按顺序把罐子浏览一遍,如果他的钱花完了(钱数=0)或者已经走过了最后一个罐子,就会立即离开商店。

由于鸡尾酒不会掩饰自己对罐子的喜爱,所以只要他现有的钱大于等于当前看到的罐子的价格,他就会购买。

鸡尾酒有n元钱,并且想买m个罐子,你能帮他算算他应该至少带多少钱才能买到m个罐子吗?

输入描述:

第一行包含三个整数n,m,k。 n代表鸡尾酒最多能带的钱(0<=n<109),m代表鸡尾酒想买的罐子数量,k代表商店里罐子的数量, 保证商店至少有m个罐子(1<=m<=k<=300)。 接下来一行包含k个整数,第i个数表示第i个罐子的价格pi。(0<=pi<=1000)

输出描述:

输出鸡尾酒购买m个罐子至少需要带的钱数。如果鸡尾酒无论如何都买不了m个罐子,输出 "poor chicken tail wine!" 示例1

输入

5 2 3 1 2 3

输出

3 示例2

输入

1 2 2 100 100

输出

poor chicken tail wine!

 题解:考虑到限制条件,倒着dp即可 1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #include<iostream> 5 #include<queue> 6 #include<stack> 7 #include<set> 8 #include<vector> 9 #include<map> 10 #include<cmath> 11 using namespace std; 12 typedef long long ll; 13 ll a[305],dp[305][305]; 14 int main() 15 { 16 ll n,m,k; 17 cin>>n>>m>>k; 18 memset(dp,0x3f3f3f3f,sizeof(dp)); 19 for(int i=1;i<=k;i++)scanf("%lld",&a[i]); 20 for(int i=1;i<=k+1;i++)dp[i][0]=0; 21 for(int i=k;i>=1;i--){ 22 for(int j=1;j<=k-i+1;j++){ 23 if(a[i]==0&&dp[i+1][j-1]==0)dp[i][j]=min(dp[i+1][j-1]+a[i]+1,dp[i][j]); 24 else dp[i][j]=min(dp[i+1][j-1]+a[i],dp[i][j]); 25 if(a[i]>dp[i+1][j]){ 26 dp[i][j]=min(dp[i][j],dp[i+1][j]); 27 } 28 } 29 } 30 if(dp[1][m]>n)printf("poor chicken tail wine!\n"); 31 else printf("%lld\n",dp[1][m]); 32 return 0; 33 } View Code

 

转载于:https://www.cnblogs.com/MekakuCityActor/p/10589317.html


最新回复(0)