推荐郑州网站建设公司广州越秀区房价
推荐郑州网站建设公司,广州越秀区房价,北京公司有哪些,wordpress 用户管理解析
呜呜呜不废啊 我只会跑n遍多重背包 感觉非常神仙的一道题 之所以只是蓝的可能是因为代码实现难度太低了吧 但感觉思想真的很难想到 也可能是我太菜了 容斥相关还是需要加强啊qwq
考虑如果没有硬币个数的限制的情况 显然就是个简单的完全背包了 然而如今有了硬币个数的限…解析
呜呜呜不废啊 我只会跑n遍多重背包 感觉非常神仙的一道题 之所以只是蓝的可能是因为代码实现难度太低了吧 但感觉思想真的很难想到 也可能是我太菜了 容斥相关还是需要加强啊qwq
考虑如果没有硬币个数的限制的情况 显然就是个简单的完全背包了 然而如今有了硬币个数的限制 所以我们要考虑容斥
利用总方案数-硬币个数超过限制的方案数求出答案
前面的总方案数就是完全背包的dp值关键就是对后面硬币个数超过限制方案数的求解
考虑第iii种硬币超过限制那么就至少要使用(di1)(d_i1)(di1)个剩下可以自由选的价值是s−ci∗(di1)s-c_i*(d_i1)s−ci∗(di1) 那么对应的方案数就是dps−ci∗(d[i]1)dp_{s-c_i*(d[i]1)}dps−ci∗(d[i]1)
但是这样会算重丫 比如某种方案可能会同时超过两种限制被减了两次 因此我们就开始容斥的常用套路再加上超过两种限制的再减去超过三种限制的再加回来四种限制都超过的
问题得以解决
代码
#includebits/stdc.h
using namespace std;
#define ll long long
#define il inline
#define debug(a,b) fprintf(stderr,a,b)
const int N3e5100;
const double eps1e-9;
inline ll read() {ll x0,f1;char cgetchar();while(!isdigit(c)) {if(c-) f-1;cgetchar();}while(isdigit(c)) {x(x1)(x3)c-0;cgetchar();}return x*f;
}int n;
ll c[5],d[5],s;
ll dp[N],o100000;
inline int calc(int x){int res(0);while(x){resx1;x1;}return res;
}
int mi[6];
int main() {
#ifndef ONLINE_JUDGE//freopen(a.in,r,stdin);//freopen(a.out,w,stdout);
#endiffor(int i1;i4;i) c[i]read();nread();mi[0]1;for(int i1;i4;i) mi[i]mi[i-1]1;dp[0]1;for(int k1;k4;k){int wc[k];for(int iw;io;i) dp[i]dp[i-w];}//for(int i0;i10;i) printf(%lld ,dp[i]);putchar(\n);while(n--){for(int i1;i4;i) d[i]read();sread();ll ans0;for(int i0;i16;i){int cntcalc(i);ll tots;for(int k1;k4;k){if(imi[k-1]) tot-c[k]*(d[k]1);}if(tot0) continue;anspow(-1,cnt)*dp[tot];//printf(\ni%d cnt%d tot%lld ans%lld\n,i,cnt,tot,ans);}printf(%lld\n,ans);}return 0;
}
/*
1 2 5 10 1
3 2 3 1 10
*/
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/89051.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!