HAOI 硬币购物
试题描述:
现在一共有4种硬币,面值各不相同,分别为ci(i=1,2,3,4)。某人去商店买东西,去了tot次,每次带di枚ci硬币,购买价值为si的货物。请问每次有多少种付款方法。
输入:
第一行包括五个数,分别为c1,c2,c3,c4和tot 接下来有tot行,每行五个数,第i+1行五个数依次为第i次购物所带四种硬币的数目和购买货物的价值(d1,d2,d3,d4,s )。各行的数两两之间用一个空格分隔。
输出:
tot行,依次为每次付款的方法数。
输入示例:
1 2 5 10 2
3 2 3 1 10
1000 2 2 2 900
输出示例:
4
27
数据范围:
0<di,s<=100000,0<tot<=1000。
这道题其实就是一个dp+容斥原理(不知道什么是容斥原理的自己上网百度去)……
首先我们先对于dp数组进行初始操作。我们定义:dp[i]是在不考虑硬币是否超限的情况下用硬币凑i元的方案数。这样我们就可以得到状态方程:dp[j]+=dp[j-c[i]](由数据发现我们的0<=j<=100000,1<=i<=4)注意:dp[0]=1
然后我们就可以进行容斥原理的操作。对于每种硬币,都有超和不超两种情况,所以最终我们只需要统计2^4=16次就够了。在记录状态的时候,我们可以用10进制的数来记录,可是在操作的时候其实是对2进制进行操作。举个例子:比如我用5记录了一种状态,5的二进制就是0101,其表达的意思就是第一种和第三种硬币超出了限度。
那么我们应该如何来表示使用硬币超过了限度?举个例子:比如当前第i种硬币有d[i]枚硬币可以用的话,如果我们用到了d[i]+1枚硬币那就是说我们用硬币超过了限度,且其他硬币是可以随意使用的,所以这样的情况应该有dp[s-c[i]*(d[i]+1)]种,如果s-c[i]*(d[i]+1)<0那方案数也就是0。其余的情况也类似。
这题是要开long long的,要不过不去……我就是这么死的……
AC代码:
#include<iostream>
#include<memory.h>
#include<stdio.h>
#include<cstdio>
#include<cctype>
using namespace std;
//--------------------------
void read(long long &x){
x=;char ch=getchar();long long f=;
for(;!isdigit(ch);ch=getchar())if(ch=='-')f=-;
for(;isdigit(ch);ch=getchar())x=x*+ch-'';
x*=f;
}
//---------------------------
long long c[],d[],s,tot,ans,cnt,sum,cur;
long long dp[+];
bool flag=;
int main(){
for(int i=;i<=;i++){
read(c[i]);
}
read(tot);
dp[]=;
for(int i=;i<=;i++){
for(int j=c[i];j<=;j++)dp[j]+=dp[j-c[i]];
}
while(tot--){
for(int i=;i<=;i++)read(d[i]);
read(s);
ans=;
for(int i=;i<;i++){
cnt=;sum=;cur=;
int t=i;
while(t>){
cur++;
if(t&)sum+=(d[cur]+)*c[cur],cnt++;
t>>=;
}
if(s<sum)continue;
if(cnt&)ans-=dp[s-sum];
else ans+=dp[s-sum];
}
printf("%lld\n",ans);
}
}
HAOI 硬币购物的更多相关文章
- [HAOI 2008]硬币购物
Description 硬币购物一共有4种硬币.面值分别为c1,c2,c3,c4.某人去商店买东西,去了tot次.每次带di枚ci硬币,买si的价值的东西.请问每次有多少种付款方法. Input 第一 ...
- 【BZOJ-1042】硬币购物 容斥原理 + 完全背包
1042: [HAOI2008]硬币购物 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 1811 Solved: 1057[Submit][Stat ...
- bzoj1042: [HAOI2008]硬币购物
#include <iostream> #include <cstdio> #include <cstring> #include <cmath> #i ...
- 【BZOJ】【1042】【HAOI2008】硬币购物
DP+容斥原理 sigh……就差一点…… 四种硬币的数量限制就是四个条件,满足条件1的方案集合为A,满足条件2的方案集合为B……我们要求的就是同时满足四个条件的方案集合$A\bigcap B\bigc ...
- 1042: [HAOI2008]硬币购物 - BZOJ
Description 硬币购物一共有4种硬币.面值分别为c1,c2,c3,c4.某人去商店买东西,去了tot次.每次带di枚ci硬币,买si的价值的东西.请问每次有多少种付款方法.Input 第一行 ...
- 【BZOJ1042】【DP + 容斥】[HAOI2008]硬币购物
Description 硬币购物一共有4种硬币.面值分别为c1,c2,c3,c4.某人去商店买东西,去了tot次.每次带di枚ci硬币,买si的价值的东西.请问每次有多少种付款方法. Input 第一 ...
- Bzoj 1042: [HAOI2008]硬币购物 容斥原理,动态规划,背包dp
1042: [HAOI2008]硬币购物 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 1747 Solved: 1015[Submit][Stat ...
- bzoj 1042: [HAOI2008]硬币购物 dp+容斥原理
题目链接 1042: [HAOI2008]硬币购物 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 1706 Solved: 985[Submit][ ...
- BZOJ 1042: [HAOI2008]硬币购物( 背包dp + 容斥原理 )
先按完全背包做一次dp, dp(x)表示x元的东西有多少种方案, 然后再容斥一下. ---------------------------------------------------------- ...
随机推荐
- JAVA之序列化A
package SwingGui.sky.com; import java.io.*; public class GameSaverTest { public static void main(Str ...
- 程序自动生成Dump文件()
前言:通过drwtsn32.NTSD.CDB等调试工具生成Dump文件, drwtsn32存在的缺点虽然NTSD.CDB可以完全解决,但并不是所有的操作系统中都安装了NTSD.CDB等调试工具.了解了 ...
- VC++大数据量绘图时无闪烁刷屏技术实现(我的理解是,在内存上作画,然后手动显示,而不再直接需要经过WM_PAINT来处理了)
http://hantayi.blog.51cto.com/1100843/383578 引言 当我们需要在用户区显示一些图形时,先把图形在客户区画上,虽然已经画好但此时我们还无法看到,还要通过 程序 ...
- ListView OnScrollListener详解(滑屏分页显示数据)
package com.action; import java.util.ArrayList; import java.util.List; import android.app.Activity; ...
- UVAlive3211 Now or later(2-SAT)
题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=33799 [思路] 2-SAT. 二分安全间隔x,先到为1后到为0, ...
- Robot Framework安装配置 windows
1.install python https://www.python.org/downloads/release/python-279/ choose "Files" -> ...
- java中字符串的比较
compareTo方法是比较两个字符串的词典顺序 也就是在字典中的顺序,比如“abcd”在“acdb”前面 大于返回1,小于返回-1 equals:比较两字符串的内容是否相同. 相同返回1,不同返回 ...
- Spice代码阅读一:Spice Client 与 Spice Server 通道建立过程
文件 方法 描述 Application.cpp init_globals() 初始化Log,ssl库,canvas(或opengl canvas)和quic压缩库 Process_cmd_line( ...
- 使用MJRefresh遇到的坑
在使用MJRefresh的时候,下拉刷新表头停在了上部,箭头并没有隐藏 解决方法:进行数据请求的时候不要使用 beginRefresh方法,要直接调用方法进行数据请求
- Android ScrollView
ScrollView 滚动视图 滚动视图用于为其它组件添加滚动条,在默认的情况下,当窗体中内容比较多,而一屏显示不下时,超出的部分不能被用户所看到.因为Android的布局管理器本身没有提供滚动屏幕的 ...