折腾了一上午……
dp[i][j]表示第i罐结束时,体积为j的“浓度”,注意这里的浓度不是平时意义的浓度,这里指的是“纯药液”
将两瓶液体混合,体积分别是kv和zv,浓度分别是a和b,混合后的浓度为:(kv*a + zv*b)/(kv+zv),化简之后就是(ka+zb)/(k+z),然后解释起来就是:k+z份的纯药液(ka+zb),不含水……
这题本身是让用贪心做,一开始没看出来,直接用DP了,然后就有个问题:同样体积,浓度满足条件时,要选浓度最小的那个!题目也不说明。
#include "stdio.h"
#include "string.h"
#define MIN(a, b) ((a)<(b)?(a):(b))
void main(){
int c;
int n, v, w;
int den[101], d, t;
int dp[101][101]; //第i罐结尾时,体积为j
int i, j, z, s;
freopen("in.txt", "r", stdin);
scanf("%d", &c);
while(c--){
scanf("%d %d %d", &n, &v, &w);
for(i=1; i<=n; i++) scanf("%d", den+i);
memset(dp, 0x7F, sizeof(dp));
for(i=1; i<=n; i++){
dp[i][1] = den[i];
for(j=2; j<=i; j++){
for(z=i-1; z>=j-1; z--){
t = dp[z][j-1]+den[i]; //总共j份纯药液
dp[i][j] = MIN(dp[i][j], t);
}
}
}
s = 0; d = 0;
for(i=1; i<=n; i++){
for(j=1; j<=i; j++){
if(dp[i][j]*1.0/j<=w && j>=s){ //注意,这里的dp[i][j]是j份的纯药液
if(j>s){
s = j;
d = dp[i][j];
}
else{
if(dp[i][j]*1.0/j<d) //选浓度小的!!!
d = dp[i][j];
}
}
}
}
if(s)
printf("%d %.2lf\n", s*v, d*0.01/s);
else
printf("0 0.00\n");
}
}
/*2570*/