POJ - 1260 Pearls

https://vjudge.net/problem/POJ-1260

题意

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

(规定买任一类的珍珠n个(价格为p),都要支付(n+10)*p的钱,即额外支付10*p)

分析

珍珠的替代必须是连续的,不能跳跃替代(因为假如用第i+2类去替代第i类珍珠,会使最终的支付价格降低,那么用第i+1类去替代第i类珍珠会使最终的支付价格更加低)。那么可以把珍珠种类分成几个区间,每个区间都以其最合适的最高类别的珍珠价格决定,最终总价格就是每个区间的花费。

dp[i]表示为以i起始到结尾的珍珠购买需要最少的价钱。则状态方程为:

dp[i]=min{dp[i+1]+(num[i]+10)*p[i]  //原始操作, dp[j+1]+(sum[j]-sum[i-1]+10)*p[j] //以j珍珠的价格买入}

#include<iostream>
#include<cmath>
#include<cstring>
#include<queue>
#include<vector>
#include<cstdio>
#include<algorithm>
#include<map>
#include<set>
#define rep(i,e) for(int i=0;i<(e);i++)
#define rep1(i,e) for(int i=1;i<=(e);i++)
#define repx(i,x,e) for(int i=(x);i<=(e);i++)
#define X first
#define Y second
#define PB push_back
#define MP make_pair
#define mset(var,val) memset(var,val,sizeof(var))
#define scd(a) scanf("%d",&a)
#define scdd(a,b) scanf("%d%d",&a,&b)
#define scddd(a,b,c) scanf("%d%d%d",&a,&b,&c)
#define pd(a) printf("%d\n",a)
#define scl(a) scanf("%lld",&a)
#define scll(a,b) scanf("%lld%lld",&a,&b)
#define sclll(a,b,c) scanf("%lld%lld%lld",&a,&b,&c)
#define IOS ios::sync_with_stdio(false);cin.tie(0)

using namespace std;
typedef long long ll;
template <class T>
void test(T a){cout<<a<<endl;}
template <class T,class T2>
void test(T a,T2 b){cout<<a<<" "<<b<<endl;}
template <class T,class T2,class T3>
void test(T a,T2 b,T3 c){cout<<a<<" "<<b<<" "<<c<<endl;}
template <class T>
inline bool scan_d(T &ret){
    char c;int sgn;
    if(c=getchar(),c==EOF) return 0;
    while(c!='-'&&(c<'0'||c>'9')) c=getchar();
    sgn=(c=='-')?-1:1;
    ret=(c=='-')?0:(c-'0');
    while(c=getchar(),c>='0'&&c<='9') ret = ret*10+(c-'0');
    ret*=sgn;
    return 1;
}
//const int N = 1e6+10;
const int inf = 0x3f3f3f3f;
const ll INF = 0x3f3f3f3f3f3f3f3fll;
const ll mod = 1000000000;
int T;

void testcase(){
    printf("Case %d:",++T);
}

const int MAXN = 5e5+5 ;
const int MAXM = 550;
const double eps = 1e-8;
const double PI = acos(-1.0);

int dp[1024];
int num[1024],p[1024],sum[1024];
int main() {
#ifdef LOCAL
    freopen("in.txt","r",stdin);
#endif // LOCAL
    int t;
    scanf("%d",&t);
    int n;
    while(t--){
        scanf("%d",&n);
        sum[0]=0;
        for(int i=1;i<=n;i++) scanf("%d%d",&num[i],&p[i]),sum[i]=sum[i-1]+num[i];
        dp[n+1]=0;
        for(int i=n;i>=1;i--){
            dp[i] = dp[i+1] + (num[i]+10)*p[i];
            for(int j=i+1;j<=n;j++){
                dp[i] = min(dp[i],dp[j+1]+(sum[j]-sum[i-1]+10)*p[j]);
            }

        }
        cout<<dp[1]<<endl;
    }
    return 0;
}

 

posted @ 2018-06-30 17:19  litos  阅读(158)  评论(0编辑  收藏  举报