bzoj1042硬币购物
题目:http://www.lydsy.com/JudgeOnline/problem.php?id=1042
dp预处理+容斥原理。
先预处理求出无限制的各面值的组成方案数 f (完全背包)。
求s [ i ]有限制的,就是s [ i ]无限制方案数 - 单种硬币一定超过限制的方案数 + 两种的 - 三种的 + 四种的。
第 k 中硬币一定超过限制的方案数就是f [ s [ i ] - c [ k ] * ( d [ k ] + 1 ) ],即确定用了 d + 1 个该硬币,刨去它们后的无限制方案数。
当 c [ k ] * ( d [ k ] + 1 ) > s [ i ] 时不用操作,即没有“超过该限制”的可能。但== s [ i ] 时还是要操作的,f [ 0 ] = 1。
以为要用高精度,结果WA。看看题解发现不用高精度,于是……
如果高精度的话,防止某次减到了负数,可以先把加的弄了(反正只有四种硬币)。
非高精AC代码:
#include<iostream>
#include<cstdio>
using namespace std;
typedef long long ll;
ll c[],d[][],tot,mx,s[],f[],ans;
void pre()
{
f[]=;///
for(int i=;i<=;i++)
for(ll j=c[i];j<=mx;j++)
f[j]+=f[j-c[i]];
}
void dfs(ll now,ll k,ll cnt,ll z)//第now次询问,第k号,选了cnt个,f目前脚标
{
if(z<)return;//不是z<=0!!
if(k==)
{
if(cnt&)ans-=f[z];
else if(cnt)ans+=f[z];
return;
}
dfs(now,k+,cnt,z);
dfs(now,k+,cnt+,z-c[k]*d[now][k]-c[k]);
}
int main()
{
for(int i=;i<=;i++)scanf("%lld",&c[i]);
scanf("%lld",&tot);
for(int i=;i<=tot;i++)
scanf("%lld%lld%lld%lld%lld",&d[i][],&d[i][],&d[i][],&d[i][],&s[i]),mx=max(mx,s[i]);
pre();
for(int i=;i<=tot;i++)
{
ans=f[s[i]];
dfs(i,,,s[i]);
printf("%lld\n",ans);
}
return ;
}
高精WA代码:
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
typedef long long ll;
const int INF=;
ll c[],d[][],tot,s[],mx,tp;
int f[INF][],ans[];
void plu(ll k,int a[],int b[])
{
int tmp[]={},lm=max(a[],b[]);
for(int i=;i<=lm;i++)
{
tmp[i]+=a[i]+b[i];
if(tmp[i]>)tmp[i]-=,tmp[i+]++;
}
tmp[]=lm;
if(tmp[tmp[]+])tmp[]++;
memcpy(f[k],tmp,sizeof tmp);
}
void pre()
{
f[][]=;f[][]=;
for(int i=;i<=;i++)
for(ll j=c[i];j<=mx;j++)
plu(j,f[j],f[j-c[i]]);
}
void print()
{
// printf("(%d)",ans[0]);
for(int i=ans[];i;i--)
printf("%d",ans[i]);
printf("\n");
}
void plu2(ll k)
{
int lm=max(ans[],f[k][]);
for(int i=;i<=lm;i++)
{
ans[i]+=f[k][i];
if(ans[i]>)ans[i]-=,ans[i+]++;
}
if(ans[ans[]+])ans[]++;
// printf("++ k=%d ",k);print();
}
void jian(ll k)
{
// int lm=max(ans[0],f[k][0]);
for(int i=;i<=f[k][];i++)
{
ans[i]-=f[k][i];
if(ans[i]<)ans[i]+=,ans[i+]--;
}
while(!ans[ans[]]&&ans[]>)ans[]--;
// printf("-- k=%d ",k);print();
}
//void debugprint()
//{
// for(int i=1;i<=s[1];i++)
// {
// printf("i=%d ",i);
// for(int j=f[i][0];j;j--)
// printf("%d",f[i][j]);
// printf("\n");
// }
//}
int main()
{
for(int i=;i<=;i++)scanf("%lld",&c[i]);
scanf("%lld",&tot);
for(int i=;i<=tot;i++)
{
scanf("%lld%lld%lld%lld%lld",&d[i][],&d[i][],&d[i][],&d[i][],&s[i]);
mx=max(mx,s[i]);
}
pre();
for(int i=;i<=tot;i++)
{
memcpy(ans,f[s[i]],sizeof f[s[i]]);//
// debugprint();
for(int u=;u<;u++)
for(int v=u+;v<=;v++)
{
tp=c[u]*d[i][u]+c[v]*d[i][v]+c[u]+c[v];
if(tp<=s[i])plu2(s[i]-tp); ///<=!!!,因为我的f[0]有值为1 ;正是要用这个1!
}
tp=c[]*d[i][]+c[]*d[i][]+c[]*d[i][]+c[]*d[i][]+c[]+c[]+c[]+c[];
if(tp<=s[i])plu2(s[i]-tp);
for(int u=;u<=;u++)
{
tp=c[u]*d[i][u]+c[u];
if(tp<=s[i])jian(s[i]-tp);
}
for(int u=;u<=;u++)
for(int v=u+;v<=;v++)
for(int j=v+;j<=;j++)
{
tp=c[u]*d[i][u]+c[v]*d[i][v]+c[j]*d[i][j]+c[u]+c[v]+c[j];
if(tp<=s[i])jian(s[i]-tp);
}
print();
}
return ;
}
bzoj1042硬币购物的更多相关文章
- bzoj1042硬币购物——递推+容斥
题目:http://www.lydsy.com/JudgeOnline/problem.php?id=1042 递推,再用容斥原理减掉多余的,加上多减的……(dfs)即可. 代码如下: #includ ...
- [bzoj1042]硬币购物
先预处理出没有上限的方案数,然后容斥,然后将所有东西的范围都变为[0,+oo),即可用预处理出的dp数组计算 1 #include<bits/stdc++.h> 2 using names ...
- BZOJ1042 [HAOI2008]硬币购物 完全背包 容斥原理
欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ1042 题目概括 硬币购物一共有4种硬币.面值分别为c1,c2,c3,c4.某人去商店买东西,去了t ...
- 【BZOJ1042】硬币购物(动态规划,容斥原理)
[BZOJ1042]硬币购物(动态规划,容斥原理) 题面 BZOJ Description 硬币购物一共有4种硬币.面值分别为c1,c2,c3,c4.某人去商店买东西,去了tot次.每次带di枚ci硬 ...
- [bzoj1042][HAOI2008][硬币购物] (容斥原理+递推)
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 ...
- 【BZOJ1042】【DP + 容斥】[HAOI2008]硬币购物
Description 硬币购物一共有4种硬币.面值分别为c1,c2,c3,c4.某人去商店买东西,去了tot次.每次带di枚ci硬币,买si的价值的东西.请问每次有多少种付款方法. Input 第一 ...
- BZOJ1042:[HAOI2008]硬币购物(DP,容斥)
Description 硬币购物一共有4种硬币.面值分别为c1,c2,c3,c4.某人去商店买东西,去了tot次.每次带di枚ci硬币,买si的价值的东西.请问每次有多少种付款方法. Input 第一 ...
随机推荐
- Visual Sudio 2012转换界面风格
点击“工具”--->"选项"--->“环境”--->“常规”将Color theme由你的“Light”改为“Dark”,即可成为黑色的界面
- python daal test
import os import sys from daal.algorithms import low_order_moments from daal.data_management import ...
- @Component 元注解
@Component 元注解 这是一个元注解,意思是它可以用于标注其他注解,被它标注的注解和它起到相同或者类似的作用.Spring用它定义了其他具有特定意义的注解如@Controller @Servi ...
- spring boot 学习(六)spring boot 各版本中使用 log4j2 记录日志
spring boot 各版本中使用 log4j2 记录日志 前言 Spring Boot中默认日志工具是 logback,只不过我不太喜欢 logback.为了更好支持 spring boot 框架 ...
- httpclient httpclient使用连接池
httpclient使用连接池 http协议是无状态的,但毕竟是基于tcp的,底层还是需要和服务器连接的, 对于需要从同一个站点抓取大量网页的程序,应该使用连接池,否则每次抓取都和web站点建立连接, ...
- JQuery, Silverlight 公用WCF
WCF web.config配置: <?xml version="1.0"?> <configuration> <system.web> < ...
- ubuntu16上传文件到服务器
用windows时候,上传文件到服务器,一般都是用xshell和xftp配合使用,用ubuntu就不需要额外安装任何软件了.只用ctrl+alt+t,打开命令行用一句话就可以上传了. 将本地war包上 ...
- MySQL性能优化方法四:SQL优化
原文链接:http://isky000.com/database/mysql-performance-tuning-sql 注:这篇文章是以 MySQL 为背景,很多内容同时适用于其他关系型数据库,需 ...
- magento的必备插件(转)
标签: 插件 magento magento插件 必备插件 Magento插件 ,插件,我要常见Magento必备插件 .. 都是免费的Magento插件,多而杂,乡亲们自己挑~~ [因收集而强大 & ...
- Linux服务器没有GUI的情况下使用matplotlib绘图
最近看到关于 python3 中用matplotlib 不进行交互画图,而是直接将图保存到硬盘,主要的一个设置就是 matplotlib.use('agg') 注明: 其实不设置 matplotl ...