链接: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! "); 31 else printf("%lld ",dp[1][m]); 32 return 0; 33 }