• F. Shovels Shop 背包DP


    题意:  

    商店里有n把铲子 每个铲子有其标价

    一个人要买k吧

    有m个优惠政策

    每个优惠政策有两个元素x,y

    表示   正好买x个铲子的时候  这x个铲子中最便宜的y个铲子免单

    求用最少的前买到k个铲子

    显然  将n个铲子升序排序好  取前k个  剩下的和本题无关!!

    然后前缀和  方便求区间的价值和  

    要求最少的钱  其实可以转化为求最大的优惠数额

    到这一步大致可以看出是一个背包问题了 

    每个优惠政策可以无限次使用  所以是一个完全背包

    即使每次价值都随着容量改变  也可以用背包法来做 

    #include<bits/stdc++.h>
    using namespace std;
    //input by bxd
    #define rep(i,a,b) for(int i=(a);i<=(b);i++)
    #define repp(i,a,b) for(int i=(a);i>=(b);--i)
    #define RI(n) scanf("%d",&(n))
    #define RII(n,m) scanf("%d%d",&n,&m)
    #define RIII(n,m,k) scanf("%d%d%d",&n,&m,&k)
    #define RS(s) scanf("%s",s);
    #define ll long long
    #define REP(i,N)  for(int i=0;i<(N);i++)
    #define CLR(A,v)  memset(A,v,sizeof A)
    //////////////////////////////////
    #define inf 0x3f3f3f3f
    #define N 200000+5
    
    int a[N];
    ll dp[N];
    ll sum[N];
    int v[N];
    int c[N];
    
    int main()
    {
        int n,m,k;
        RIII(n,m,k);
        rep(i,1,n)
        RI(a[i]);
        sort(a+1,a+1+n);
    
        rep(i,1,n)
        sum[i]=sum[i-1]+a[i];
        rep(i,1,m)
        RII(v[i],c[i]);
    
        rep(j,1,k)
        rep(i,1,m)
        if(j>=v[i])
        dp[j]=max(dp[j],dp[j-v[i]]+sum[j-v[i]+c[i]]-sum[j-v[i]]);
        cout<<sum[k]-dp[k];
    
        return 0;
    }
    View Code

    将背包的两个for循环顺序交换一下就会wa ?因为这种顺序是只取只取一个  (优惠一次一次只能用一种) 为分组背包!

    更加简便的题解:

    #include<bits/stdc++.h>
    using namespace std;
    typedef pair<int,int> P;
    const int maxn=2e5+10;
    const int maxk=2e3+10;
    
    int n,m,k;
    int a[maxn],s[maxn];
    int g[maxk];
    int f[maxk];
    
    int main()
    {
        cin>>n>>m>>k;
        for(int i=1;i<=n;i++) scanf("%d",&a[i]);
        for(int i=1,x,y;i<=m;i++)
        {
            scanf("%d%d",&x,&y);
            if(x<=k) g[x]=max(g[x],y);
        }
        sort(a+1,a+n+1);
        for(int i=1;i<=k;i++) s[i]=s[i-1]+a[i];
        for(int i=1;i<=k;i++)
        {
            f[i]=0;
            for(int j=0;j<i;j++)
                f[i]=max(f[i],f[j]+s[j+g[i-j]]-s[j]);
        }
        cout<<s[k]-f[k]<<endl;
    }
    View Code
  • 相关阅读:
    Kmeans中文聚类
    第四周周总结
    数据清洗第一天
    第三周周总结
    关于sqoop上传mysql数据到hive报错的问题
    天津东软实训第十一天——Hive连接JDBC
    天津东软实训第十天——Hive配置
    天津东软实训第九天——MapReduce实战
    天津东软实训第八天------倒排索引
    Intellij IDEA 创建maven项目,利用API操作HDFS
  • 原文地址:https://www.cnblogs.com/bxd123/p/10731129.html
Copyright © 2020-2023  润新知