zoukankan      html  css  js  c++  java
  • 没有找零 状压dp

    没有找零 状压dp

    约翰到商场购物,他的钱包里有K(1 <= K <= 16)个硬币,面值的范围是1..100,000,000。约翰想按顺序买 N个物品(1 <= N <= 100,000),第i个物品需要花费c(i)块钱,(1 <= c(i) <= 10,000)。在依次进行的购买N个物品的过程中,约翰可以随时停下来付款,每次付款只用一个硬币,支付购买的内容是从上一次支付后开始到现在的这些所有物品(前提是该硬币足以支付这些物品的费用)。不幸的是,商场的收银机坏了,如果约翰支付的硬币面值大于所需的费用,他不会得到任何找零。请计算出在购买完N个物品后,约翰最多剩下多少钱。如果无法完成购买,输出-1。

    如果我们枚举k的全排列是肯定超时的。显然对于一种硬币的选择方案,尽可能选更多的物品更优,没有必要枚举全排列。所以(f[i])表示当前选硬币的状态为(i),在第i个物品处,用第j个硬币能到达的最远处。那么转移方程为(f[i]=f[j]+a[f[j]][k]),k可以通过i,j判断出来。别忘记要预处理a。那么时间复杂度则为(O(knlog_2n+2^kn))

    感觉状压dp就是在dp减少无用状态的前提下贪心而已。

    #include <cstdio>
    #include <algorithm>
    using namespace std;
    
    const int maxn=1e5+5, maxk=20;
    int k, n, coins[maxn], things[maxn], pre[maxn];
    // pre:物品的前缀和
    int a[maxn][maxk]; //在第i个位置,用第j个硬币的能到达的地方。
    int f[int(1e6)]; //一个状态最远能到达的地方
    
    int calc(int now){
        int re=0;
        for (int i=k; i>0; --i){
            re+=(1-(now&1))*coins[i];
            now>>=1;
        }
        return re;
    }
    
    int main(){
        scanf("%d%d", &k, &n);
        for (int i=1; i<=k; ++i) scanf("%d", &coins[i]);
        for (int i=1; i<=n; ++i){
            scanf("%d", &things[i]);
            pre[i]=pre[i-1]+things[i];
        }
        int t, t2;
        for (int i=1; i<=n; ++i)
            for (int j=1; j<=k; ++j){
                t=pre[i-1]+coins[j];
                a[i][j]=upper_bound(pre+i, pre+n+1, t)-pre-i;
            }
        for (int i=0; i<(1<<k); ++i){
            t=1;
            for (int j=k; j>=1; --j){ //枚举前一个状态
                if (t&i){
                    t2=i-t;
                    f[i]=max(f[i], f[t2]+a[f[t2]+1][j]);
                }
                t<<=1;
            }
        }
        int ans=0; bool flag=false;
        for (int i=0; i<(1<<k); ++i){
            if (f[i]==n&&calc(i)>ans) ans=calc(i);
            if (f[i]==n) flag=true;
        }
        printf("%d", flag?ans:-1);
        return 0;
    }
    
  • 相关阅读:
    shell中的for循环
    tty相关
    udev规则
    find中perm参数
    日志级别的选择:Debug、Info、Warn、Error还是Fatal
    云计算、云存储、大数据
    JSON数据解析(python3.4)
    38、友盟统计
    37、iamgeview 图层叠加
    36、imageview的坑
  • 原文地址:https://www.cnblogs.com/MyNameIsPc/p/7701096.html
Copyright © 2011-2022 走看看