学习笔记5:dp的应用

F - Sensor Optimization Dilemma (atcoder.jp)

分析:一共两种物品,有n个需要覆盖的区间。

我们思考,如果成功方案存在时,对于一个区间,我们只需要知道在这个区间中,其中一种物品的个数就可以推算出另一种,数据范围个数为1e3,对于每个区间枚举个数是可行的,这时我们可以设计状态 dp[i][j]  到第 i 个区间时用了 j 个物品1时需要的物品2的个数。

转移方程是dp[i][j+k] =min(dp[i][j+k],dp[i-1][j]+tt) tt为当前区间减去k个物品1后,需要的物品2的个数。初始化dp数组是正无穷,dp[0][i]为0,最后计算答案是所有dp[n][i]<=物品2个数的方案的最小值

#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
#define int long long
const int N=1000010;
int a[N],l[2],k[2],c[2];
int dp[1010][1010];
signed main(){
    int n;
    cin>>n;
    for(int i=1;i<=n;i++) cin>>a[i];
    cin>>l[0]>>c[0]>>k[0];
    cin>>l[1]>>c[1]>>k[1];
    memset(dp,0x3f,sizeof dp);
    for(int i=0;i<1010;i++){
        for(int j=0;j<1010;j++){
            dp[i][j]=1e18;
        }
    }
    for(int i=0;i<=k[0];i++)dp[0][i]=0;
    for(int i=1;i<=n;i++){
        int now=(a[i]+l[0]-1)/l[0];//当前区域最多花费
        for(int j=0;j<=now;j++){
            for(int kk=0;kk+j<=k[0];kk++){
                int tt=(max((int)0,a[i]-j*l[0])+l[1]-1)/l[1];
                dp[i][j+kk]=min(dp[i][j+kk],dp[i-1][kk]+tt);
            }
        }
    }
    int ans=1e18;
    for(int i=0;i<=k[0];i++){
       // cout<<dp[n][i]<<endl;
       if(dp[n][i]<=k[1]) ans=min(ans,dp[n][i]*c[1]+i*c[0]);
    }
    if(ans==1e18) cout<<-1<<endl;
    else cout<<ans<<endl;
    
    
}

·

  • 11
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值