满减 HRBUST - 2455

https://vjudge.net/problem/HRBUST-2455

有两种优惠方式,一是满400减100,另外一种是商品自带折扣,二者不可叠加

dp[i][j]表示前i种商品,(参与满400减100活动的商品价格之和)%400 == j 的最少总花费,这里默认后面的商品都使用自身折扣,

为了避免小数,把价格A[i]都扩大十倍A[i]*=10。

容易得到转移方程 dp[i][j] = min(dp[i-1][x]+j*10+(x+A[i]/10)/400*3000-x*10-A[i]/10*B[i],dp[i-1][j])

其中 x = (j-A[i]+1200)%400

边界dp[0][0]表示所有商品只使用自身折扣

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
#define int long long
int t;
int N;
int A[1003];
int B[1003];
int dp[1004][400];
double ans =0.0;
const int INF = 1e18;
signed main()
{
    scanf("%lld",&t);
    while(t--){
        int tmp =0;
        scanf("%lld",&N);
        for(int i=1;i<=N;i++){
            scanf("%lld%lld",&A[i],&B[i]);
            tmp+=A[i]*B[i];
            A[i]*=10;
            for(int j=0;j<400;j++){
                dp[0][j]=dp[i][j]=INF;
            }
        }
        dp[0][0]=tmp;
        int x ;
        for(int i=1;i<=N;i++){
            for(int j=0;j<400;j++){
                x= (j-A[i]/10+1200)%400;
                dp[i][j]=min(dp[i-1][x]-(A[i]/10ll)*B[i]+j*10ll-x*10ll+((x+A[i]/10ll)/400ll)*3000ll,dp[i-1][j]);
            }
        }
       
        tmp = 1e18;
        for(int j=0;j<400;j++){
            tmp = min(tmp,dp[N][j]);
        }
        
        printf("%.1f\n",tmp*0.1);

    }
    
}

 

posted @ 2019-12-10 09:00  liulex  阅读(192)  评论(0编辑  收藏  举报