F

简单dp。

题目大意:有n种珍珠,这n种珍珠有不同的需求量,不同的价格,价格越高,质量越高,在购买每一种珍珠时,都需要在原来的基础上多买10个。也就是说如果需要买x种珍珠,那就要付x+10个的钱。每一种珍珠必须购买大于等于自身价格的珍珠

输入一个t(100以内)表示t组测试,一个n,n种珍珠,a[i]和p[i]分别表示第i种珍珠的需求量个价格。价格严格递增,问最少的花费。

题解:定义dp[i]为购买第i种珍珠所需要的总的花费。第i种珍珠可以单独购买,也可以和前边的一块购买。这里的前边的一定是i-1,i-1和i-2,或i-1,i-2,i-3。注意一定是连续的,因为价格严格递增一定不会出现只买i和i-2而不买i-1的这种情况,因为i的价格一定是高于i-1的,i-2和i-1一块购买需要的花费一定小于和i一块买的花费。

所以状态转移方程:

  1 直接买,dp[i]=dp[i-1]+(arr[i]+10)*p[i];

  2 和前边的一块:

    for(j,0,i) dp[i]=min(dp[i],dp[j]+(sum[i]-sum[j]+10)*p[i])

code:

  

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll N=1E5+7;
ll dp[N];
ll arr[N],p[N];
ll sum[N];
void solve()
{
    memset(sum,0,sizeof sum);
    memset(dp,0,sizeof dp);
    ll n;
    cin>>n;
    for(ll i=1;i<=n;i++){
        cin>>arr[i]>>p[i];
        sum[i]=sum[i-1]+arr[i];
    }
    for(ll i=1;i<=n;i++){
        dp[i]=dp[i-1]+(arr[i]+10)*p[i];
        for(ll j=0;j<i;j++)
            dp[i]=min(dp[i],dp[j]+(sum[i]-sum[j]+10)*p[i]);
    }
    cout<<dp[n]<<endl;
}
int main(){
    ios::sync_with_stdio(0);
    ll t;cin>>t;
    while(t--) solve();

    return 0;
}
原文地址:https://www.cnblogs.com/Accepting/p/12532675.html