题目描述

你有n个硬币,第i硬币面值为ai,现在总队长想知道如果丢掉了某个硬币,剩下的硬币能组成多少种价值?(0价值不算)

输入格式

第一行一个整数n

第二行n个整数。,a1,a2…an。

1<=n<=100,1<=ai<=3000

输出格式

输出n行

第i行表示没有第i个硬币能组成多少种价值。


显然是个背包题,代价设计为硬币面值,价值设计为有几种方案组成当前面值。

那么设dp(i,j)表示前i个硬币有几种方案组成价值j,可以得出转移方程:

\[if(j>=val[i])dp[i][j]+=dp[i-1][j-val[i]]\\
else:dp[i][j]=dp[i-1][j]
\]

压成一维之后:

\[dp[j]+=dp[j-val[i]];val[i]≤j≤m
\]

那么我们发现每一位的j可以由若干个状态更新过来。根据加法交换律,某个编号为i的硬币更新j状态的dp(j-val(i))先加后加都无所谓。根据这一点,我们可以认为任意一个硬币是最后被加进去的。

结合我们的结论和题目,当我们丢掉了一个硬币之后就相当于撤销这个硬币对dp数组的贡献。我们可以认为它是最后被更新上去的,所以我们只需要把更新的操作反着执行一遍即可:

for(register int j=val[i];j<=m;j++) dp[j]-=dp[j-val[i]];

然后我们的答案是能凑出的价值的个数,只需要枚举求一下有那些价值可以被≥1种方案凑出即可。

时间复杂度为O(NM)。

* dp数组在计算中会爆longlong,记得开高精。或者int128

* c数组可以直接用一个变量sum代替

#include<iostream>
#include<cstring>
#include<cstdio>
#define maxn 101
#define maxm 300001
using namespace std; __int128 dp[maxm];
int n,m,val[maxn],c[maxm]; inline int read(){
register int x(0),f(1); register char c(getchar());
while(c<'0'||'9'<c){ if(c=='-') f=-1; c=getchar(); }
while('0'<=c&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
return x*f;
} inline void update(){
for(register int i=1;i<=m;i++) c[i]=c[i-1]+(dp[i]>0);
}
inline void add(const int &val){
for(register int i=m;i>=val;i--) dp[i]+=dp[i-val];
}
inline void del(const int &val){
for(register int i=val;i<=m;i++) dp[i]-=dp[i-val];
} int main(){
n=read(),dp[0]=1;
for(register int i=1;i<=n;i++) val[i]=read(),m+=val[i];
for(register int i=1;i<=n;i++) add(val[i]);
for(register int i=1;i<=n;i++){
del(val[i]),update(),printf("%d\n",c[m]),add(val[i]);
}
return 0;
}

入门OJ:Coin的更多相关文章

  1. 【入门OJ】2003: [Noip模拟题]寻找羔羊

    这里可以复制样例: 样例输入: agnusbgnus 样例输出: 6 这里是链接:[入门OJ]2003: [Noip模拟题]寻找羔羊 这里是题解: 题目是求子串个数,且要求简单去重. 对于一个例子(a ...

  2. 【大视野入门OJ】1099:歌德巴赫猜想

    Description 歌德巴赫猜想大家都很熟悉吧?给一个数,能够分解成两个素数的和.现在要给你一个n,6 <= n < 1000000,让你求他会分解成哪两个素数?如果存在多组解,则要求 ...

  3. 【大视野入门OJ】1083:数组的二分查找

    Description 在1500个整数中查整数x的位置,这些数已经从小到大排序了.若存在则输出其位置,若不存在则输出-1. Input 第一行,一个整数x 后面1500行,每行一个整数 Output ...

  4. 入门oj 6492: 小B的询问

    Description 小B有一个序列,包含N个1~K之间的整数.他一共有M个询问,每个询问给定一个区间[L..R],求Sigma(c(i)^2)的值,其中i的值从1到K,其中c(i)表示数字i在[L ...

  5. 入门oj 5499: 讲话模式

    Description 每个人说话都有口头禅,现给出一个字符串,请求出其中出现次数最多的单词(不区分大小写). Input 输入一行,长度小于等于1048576的字符串输入至少包含一个字母或数字 Ou ...

  6. 入门oj 6451: The XOR Largest Pair之二

    Description 今天小W用了1s不到的时候完成了这样一个题:在给定的N个整数 A_1,A_2,-,A_N中选出两个进行异或运算,得到的结果最大是多少?正当他志得意满时,L老师亮出了另一个题:给 ...

  7. 入门OJ:photo

    题目描述 有N个人,来自K个家族.他们排成一行准备照相,但是由于天生的排外性,每个人都希望和本家族的人站在一起,中间不要加入别的家族的人.问最少从队列中去掉多少个就可以达到这个目的. 输入格式 第一行 ...

  8. 入门OJ:简单的网络游戏

    题目描述 在某款极具技术含量的网络游戏中,佳佳靠着他的聪明智慧垄断了游戏中的油田系统.油田里有许多油井,这些油井排成一个M*N的矩形.每个油井都有一个固定的采油量.每两个相邻的油井之间有一条公路,这些 ...

  9. 入门OJ:最短路径树入门

    题目描述 n个城市用m条双向公路连接,使得任意两个城市都能直接或间接地连通.其中城市编号为1..n,公路编号为1..m.任意个两个城市间的货物运输会选择最短路径,把这n*(n-1)条最短路径的和记为S ...

随机推荐

  1. css 07-浮动

    07-浮动.md #文本主要内容 标准文档流 标准文档流的特性 行内元素和块级元素 行内元素和块级元素的相互转换 浮动的性质 浮动的清除 浏览器的兼容性问题 浮动中margin相关 关于margin的 ...

  2. 网站开发学习Python实现-Django学习-总结(6.1.2)

    @ 目录 1.MVT 2.模型 3.视图 4.模板 5.常用的命令 6.pycharm创建django工程 关于作者 1.MVT 项目结构如下,其中项目同名文件夹为配置文件 每一个项目有多个应用(未考 ...

  3. Open SSH CVE-2020-15778

    Open SSH OpenSSH 是用于使用 SSH 协议进行远程登录的一个开源实现.通过对交互的流量进行加密防止窃听,连接劫持以及其他攻击.OpenSSH 由 OpenBSD 项目的一些开发人员开发 ...

  4. VueJs(15)--- Webstorm+Chrome 调试Vue项目

    Webstorm+Chrome 调试Vue项目 前言 在项目开发中,Debug模式是非常有必要的,后端对于IDEA工具而言Debug模式非常方便,但前端WebStorm而言如果启用Debug模式是需要 ...

  5. ucore操作系统学习(七) ucore lab7同步互斥

    1. ucore lab7介绍 ucore在前面的实验中实现了进程/线程机制,并在lab6中实现了抢占式的线程调度机制.基于中断的抢占式线程调度机制使得线程在执行的过程中随时可能被操作系统打断,被阻塞 ...

  6. 云服务器部署LAMP

    一.安装Apache 1.安装httpd服务: sudo yum install httpd 2.开启服务: sudo systemctl start httpd 3.访问服务器IP成功显示Testi ...

  7. java动态代理实现与原理详细分析(转)

    关于Java中的动态代理,我们首先需要了解的是一种常用的设计模式--代理模式,而对于代理,根据创建代理类的时间点,又可以分为静态代理和动态代理. 一.代理模式    代理模式是常用的java设计模式, ...

  8. BOM主数据-用ECN实现可变BOM

    用ECN变更号实现可变BOM:通过ECN变更号的参数类型来实现BOM的可变配置. 物料编号:2104 (1)首先BOM的父项物料主数据<基本数据1>必须设置栏位"参数有效值&qu ...

  9. 3. Longest Substring Without Repeating Characters寻找不重复的最大子串

    首先弄清楚Substring和Subsequence,前者是子串,要求连续,后者是子序列,可以不连续 public int lengthOfLongestSubstring(String s) { / ...

  10. CAP理论和BASE理论及数据库的ACID中关于一致性及不同点的思考

    CAP定理又被称作是布鲁尔定理,是加州大学伯克利分销计算机科学家里克在2000年提出,是分布式理论基础. CAP:是分布式系统的理论基础 [一致性  可用性   分区容错性] BASE理论是对CAP中 ...