P3092 [USACO13NOV] No Change G

原题链接

题解

请看代码upperbound是为了找出最大的小于等于

code

#include<bits/stdc++.h>
using namespace std;
int a[20]={0},sum[100005]={0},dp[1<<22]={0};//dp代表当前状态能买多少件商品,sum代表买前i间商品需要多少钱,a代表每个硬币的价值
int f[1<<22]={0};//代表每个状态要花多少钱
int main()
{
    int k,n;
    cin>>k>>n;
    for(int i=1;i<=k;i++) cin>>a[i];

    for(int i=1;i<(1<<k);i++)
        for(int j=k-1;j>=0;j--) f[i]+=((i>>j)&1)*a[j+1];

    for(int i=1;i<=n;i++)
    {
        int x;
        cin>>x;
        sum[i]=sum[i-1]+x;
    }

    int ans=-1,total=f[(1<<k)-1];
    for(int i=1;i<(1<<k);i++)
    {
        for(int j=k-1;j>=0;j--)
        {
            if((i>>j)&1)//上一次付款
            {
                int pre=i^(1<<j);
                int temp=upper_bound(sum+1,sum+1+n,sum[dp[pre]]+a[j+1])-sum-1;//每个状态代表使用这些硬币后能买到的最多的商品,但是不确定使用顺序,所以每个都遍历一遍
                dp[i]=max(temp,dp[i]);
            }
        }
        if(dp[i]==n) ans=max(ans,total-f[i]);//f[i] 没有单调性
    }
    cout<<ans;
    return 0;
}

posted @   纯粹的  阅读(5)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 从HTTP原因短语缺失研究HTTP/2和HTTP/3的设计差异
· 三行代码完成国际化适配,妙~啊~
点击右上角即可分享
微信分享提示