这次的题目也真心水
题目大意就是:给出几类珍珠,以及它们的单价,要求用最少的钱就可以买到相同数量的,相同(或更高)质量的珍珠。
说白了就是贵的可以代替便宜的
我们设f[i]表示买前i种珍珠的最少花费,然后我们对于f[i][j],只需要向前枚举一段,把这一段的珍珠都用第i种来代替。
所以对于这种一段的和只需要前缀和一下即可,转移方程:
f[i]=min(f[i],f[j]+(sum[i]-s[j]+10)*p[i])
可以一边读一边做
CODE
#include<cstdio>
using namespace std;
const int N=105;
int t,n,a,p,f[N],sum[N],tot;
inline char tc(void)
{
static char fl[100000],*A=fl,*B=fl;
return A==B&&(B=(A=fl)+fread(fl,1,100000,stdin),A==B)?EOF:*A++;
}
inline void read(int &x)
{
x=0; char ch=tc();
while (ch<'0'||ch>'9') ch=tc();
while (ch>='0'&&ch<='9') x=x*10+ch-'0',ch=tc();
}
inline void write(int x)
{
if (x/10) write(x/10);
putchar(x%10+'0');
}
inline int min(int a,int b)
{
return a<b?a:b;
}
int main()
{
//freopen("CODE.in","r",stdin); freopen("CODE.out","w",stdout);
register int i,j;
for (read(t);t;--t)
{
for (read(n),tot=0,sum[0]=0,i=1;i<=n;++i)
{
read(a); read(p);
sum[i]=sum[i-1]+a; tot+=(a+10)*p; f[i]=tot;
for (j=0;j<i;++j)
f[i]=min(f[i],f[j]+(sum[i]-sum[j]+10)*p);
}
write(f[n]); putchar('
');
}
return 0;
}