LG3092 「USACO2013NOV」No Change 状压DP
Posted liubainian
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LG3092 「USACO2013NOV」No Change 状压DP相关的知识,希望对你有一定的参考价值。
问题描述
https://www.luogu.org/problem/P3092
题解
观察到 \(k \le 16\) ,自然想到对 \(k\) 状压。
设 \(opt[i]\) 代表使用硬币状况为 \(i\) 时,最多可以买到 \(opt[i]\) 个物品。
然后 \(opt[i]\) 在DP过程中二分求出。
\(\mathrmCode\)
#include<bits/stdc++.h>
using namespace std;
template <typename Tp>
void read(Tp &x)
x=0;char ch=1;int fh;
while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
if(ch=='-')
fh=-1;ch=getchar();
else fh=1;
while(ch>='0'&&ch<='9')
x=(x<<1)+(x<<3)+ch-'0';
ch=getchar();
x*=fh;
int n,k;
int mon[23],s[1000000],opt[1000000],ans=-1;
int cot[1000000];
int find(int x)
int l=1,r=n,mid,res=0;
while(l<=r)
mid=(l+r)>>1;
if(s[mid]<=x)
l=mid+1,res=mid;
else r=mid-1;
return res;
int main()
read(k);read(n);
for(int i=0;i<k;i++) read(mon[i]);
for(int i=1;i<=n;i++)
read(cot[i]);s[i]=s[i-1]+cot[i];
for(int i=0;i<(1<<k);i++)
for(int j=0;j<k;j++)
int pos=(i&(1<<j));
if(!pos) continue;
opt[i]=max(opt[i],find(s[opt[i xor (1<<j)]]+mon[j]));
int sum;
for(int i=0;i<(1<<k);i++)
if(opt[i]!=n) continue;
sum=0;
for(int j=0;j<k;j++)
if(!(i&(1<<j))) sum+=mon[j];
ans=max(ans,sum);
printf("%d\n",ans);
return 0;
以上是关于LG3092 「USACO2013NOV」No Change 状压DP的主要内容,如果未能解决你的问题,请参考以下文章
洛谷 P3092 [USACO13NOV]没有找零No Change
Luogu3092:[USACO13NOV]No Change
P3092 [USACO13NOV]没有找零No Change
P3092 [USACO13NOV]没有找零No Change