洛谷P1450 [HAOI2008]硬币购物
2018-06-17 21:15:27来源:未知 阅读 ()
题目描述
硬币购物一共有4种硬币。面值分别为c1,c2,c3,c4。某人去商店买东西,去了tot次。每次带di枚ci硬币,买si的价值的东西。请问每次有多少种付款方法。
输入输出格式
输入格式:
第一行 c1,c2,c3,c4,tot 下面tot行 d1,d2,d3,d4,s
输出格式:
每次的方法数
输入输出样例
1 2 5 10 2 3 2 3 1 10 1000 2 2 2 900
4 27
说明
di,s<=100000
tot<=1000
[HAOI2008]
首先考虑如果去掉限制,那就是一个裸的完全背包问题
加上限制的话,我们可以考虑先求出没有限制的,再把超出限制的减去
体现到代码上,就是dp[num]减去dp[num-C[i]*(D[i]+1)]
这样每个都减去
但是会有减重的部分,再加回去
#include<iostream> #include<cstdio> #define LL long long using namespace std; const LL MAXN=1e6+10; LL C[5],S[5]; inline char nc() { static char buf[MAXN],*p1=buf,*p2=buf; return p1==p2&&(p2=(p1=buf)+fread(buf,1,MAXN,stdin),p1==p2)?EOF:*p1++; } inline LL read() { char c=nc();LL x=0,f=1; while(c<'0'||c>'9'){if(c=='-')f=-1;c=nc();} while(c>='0'&&c<='9'){x=x*10+c-'0';c=nc();} return x*f; } LL dp[MAXN],ans; void dfs(LL now,LL zt,LL num) { if(num<0) return ; if(now==5) { if(zt&1) ans-=dp[num]; else ans+=dp[num]; return ; } dfs(now+1,zt+1,num-C[now]*(S[now]+1) ); dfs(now+1,zt,num); } int main() { #ifdef WIN32 freopen("a.in","r",stdin); #else #endif for(LL i=1;i<=4;i++) C[i]=read(); dp[0]=1; for(LL i=1;i<=4;i++) for(LL j=C[i];j<=100001;j++) dp[j]+=dp[j-C[i]]; LL K=read(); while(K--) { for(LL i=1;i<=4;i++) S[i]=read(); LL num=read(); ans=0; dfs(1,0,num); printf("%lld\n",ans); } return 0; }
标签:
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有
- 洛谷P1164->小A点菜 2020-05-18
- 洛谷P1907口算练习题 2020-03-24
- 结题报告--P5551洛谷--Chino的树学 2020-03-13
- 结题报告--洛谷P3915 2020-03-13
- 洛谷P1034 矩形覆盖 2020-03-10
IDC资讯: 主机资讯 注册资讯 托管资讯 vps资讯 网站建设
网站运营: 建站经验 策划盈利 搜索优化 网站推广 免费资源
网络编程: Asp.Net编程 Asp编程 Php编程 Xml编程 Access Mssql Mysql 其它
服务器技术: Web服务器 Ftp服务器 Mail服务器 Dns服务器 安全防护
软件技巧: 其它软件 Word Excel Powerpoint Ghost Vista QQ空间 QQ FlashGet 迅雷
网页制作: FrontPages Dreamweaver Javascript css photoshop fireworks Flash