给定平均分和科目数,求可能的最低绩点和最高绩点。
容量为sum,41件物品(60-100分),完全背包。
费用为件数的1,和所需要的分数。
价值是绩点。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
#include <algorithm>
using namespacestd;
const int maxn =45;
const int maxV =100 * maxn;
double dp[maxV][maxn];
int c[maxn];//花费
double v[maxn];//价值
double f[maxV][maxn];
const int INF =maxV;
double gpai(int s)
{
if (s >=85) {
return4.0;
}
else if(s >= 80)
return3.5;
else if(s >= 75)
return3.0;
else if(s >= 70)
return2.5;
else if(s >= 60)
return2.0;
elsereturn 0;
}
void prepro()
{
for(int i =1;i <= 41;i ++)
{
c[i] = i -1;
v[i] =gpai(i + 59);
}
}
int main()
{
prepro();
int T;
scanf("%d",&T);
int sum,n;
while(T --)
{
scanf("%d%d",&sum,&n);
sum *= n;
sum -= 60 * n;
memset(dp,0,sizeof(dp));
for (int i =0; i <= 41; i ++) {
for (int j =0; j <= sum; j++) {
f[j][i] = INF;
}
}
f[0][0] =0;
for (int i =1; i <= 41; i ++) {//物品编号i代表i + 59分
for (int j =0; j <= sum; j ++) {//容量
for(int k =0;k <= n;k ++){
if(j -c[i] >= 0 && k -1 >= 0)
{
dp[j][k] =max(dp[j][k] ,dp[j - c[i]][k -1] + v[i]);
f[j][k] =min(f[j][k] ,f[j - c[i]][k -1] + v[i]);
}
}
}
}
printf("%.4lf %.4lf\n",f[sum][n] / n,dp[sum][n] / n);
}
return0;
}