非常经典的背包题目
/*
+和-的顺更新序不一样,+是从小到大依次更新,-是从大到小依次更新,所以不能同时更新两个变量,故要进行两次完全背包
除此之外,由于有可能先大于100,然后再减去某数获得小于100的数,因此数组不能只开到100,
具体应至少开到50*100这么大,可以保证最多100次使用且获得小于100的数。
*/
#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
int min(int a,int b)
{
return a>b?b:a;
}
int dp[20001];
int main()
{
int r;
cin>>r;
while (r--)
{
memset (dp,0,sizeof(dp));
int v[7];
int m=0;
double sum=0;
for (int i=1;i<=6;i++)
cin>>v[i];
memset(dp,0,sizeof(dp));
for (int i=1;i<=20000;i++)
dp[i]=2000;
for (int i=1;i<=6;i++)
{
for (int t=v[i];t<=20000;t++)
{
dp[t]=min(dp[t],dp[t-v[i]]+1);
}
}
for (int i=1;i<=6;i++)
{
for (int t=20000-v[i];t>=1;t--)
{
dp[t]=min(dp[t],dp[t+v[i]]+1);
}
}
for (int i=1;i<=100;i++)
{
sum+=dp[i];
if (dp[i]>m)
m=dp[i];
}
printf("%.2f %d\n",sum/100,m);
}
return 0;
}