POJ1260

这次的题目也真心水

题目大意就是:给出几类珍珠,以及它们的单价,要求用最少的钱就可以买到相同数量的,相同(或更高)质量的珍珠。

说白了就是贵的可以代替便宜的

我们设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('\n');
    }
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/cjjsb/p/9028831.html