首页 > 其他分享 >题解与求助 P2347 [NOIP1996 提高组] 砝码称重

题解与求助 P2347 [NOIP1996 提高组] 砝码称重

时间:2024-07-10 10:54:14浏览次数:9  
标签:2000000 int 题解 P2347 砝码 NOIP1996 include dp mathrm

P2347 [NOIP1996 提高组] 砝码称重


题目描述

设有 $1\mathrm{g}$、$2\mathrm{g}$、$3\mathrm{g}$、$5\mathrm{g}$、$10\mathrm{g}$、$20\mathrm{g}$ 的砝码各若干枚(其总重 $ \le 1000$),可以表示成多少种重量?

输入格式

输入方式:$a_1 , a_2 ,a_3 , a_4 , a_5 ,a_6$

(表示 $1\mathrm{g}$ 砝码有 $a_1$ 个,$2\mathrm{g}$ 砝码有 $a_2$ 个,$\dots$,$20\mathrm{g}$ 砝码有 $a_6$ 个)

输出格式

输出方式:Total=N

($N$ 表示用这些砝码能称出的不同重量的个数,但不包括一个砝码也不用的情况)

样例 #1

样例输入 #1

1 1 0 0 0 0

样例输出 #1

Total=3

题解1:

#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<stdio.h>
#include<vector>//Vector动态容器
#include<algorithm>
#include<stack>//栈
#include<unordered_map>//哈希表
#include<map>
#include<queue>//队列
using namespace std;
int dp[10000001];
int s, n, d;
int w[2000000] = {0,1,2,3,5,10,20};
int val[2000000];
int num[2000000];
int vis[2000000];
int a;
int ans;
int sum = 0;
int main(){
	for (int i = 1; i <= 6; i++){//录入砝码数
		cin >> a;
		sum += a;
		num[i] = a;
	}
	dp[0] = 1;//状态转移的开始 因为不存在一个砝码都不用的情况,所以只能由dp[0]转移
	for (int i = 1; i <= sum; i++) {
		for (int q = 1; q <= num[i]; q++)
			for (int j = 1000; j >= 0; j--){
				if (dp[j] == 1)//如果质量为2成立那么2+2也成立
					dp[j + w[i]] = 1;
			}
	}
	for(int i= 1;i<=1000;i++){
		if (dp[i])
			ans++;
	}
	cout << "Total=" << ans;
}


题解2:

这个题和多重背包如出一辙,但是没有背包问题的“限制”,唯一给的是背包总重不超过1000

那么本蒟蒻就顺手敲了个多重背包的解,但是一开始我也没做出来,我输出的是dp[1000],过了99%的点。

后来仔细钻研改进,发现了这个题解,


#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<stdio.h>
#include<vector>//Vector动态容器
#include<algorithm>
#include<stack>//栈
#include<unordered_map>//哈希表
#include<map>
#include<queue>//队列
using namespace std;
int dp[10000001];
int s, n, d;
int w[2000000] = {0,1,2,3,5,10,20};
int val[2000000];
int num[2000000];
int vis[2000000];
int a;
int sum = 0;
int ans = 0;
int main(){
	for (int i = 1; i <= 6; i++){//录入砝码数
		cin >> a;
		sum += a;
		num[i] = a;
	}
	for (int i = 1; i <= sum; i++) {
		for (int q = 1; q <= num[i]; q++)
			for (int j = 1000; j >= w[i]; j--){
				dp[j] = max(dp[j], dp[j - w[i]] + w[i]);
			}
	}
	for (int i = 1; i <= 1000; i++)
		if (dp[i] == i)
			ans++;
	cout << "Total=" << ans;
}

原错误题解如下:

#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<stdio.h>
#include<vector>//Vector动态容器
#include<algorithm>
#include<stack>//栈
#include<unordered_map>//哈希表
#include<map>
#include<queue>//队列
using namespace std;
int dp[10000001];
int s, n, d;
int w[2000000] = {0,1,2,3,5,10,20};
int val[2000000];
int num[2000000];
int vis[2000000];
int a;
int sum = 0;
int main(){
	for (int i = 1; i <= 6; i++){//录入砝码数
		cin >> a;
		sum += a;
		num[i] = a;
	}
	for (int i = 1; i <= sum; i++) {
		for (int q = 1; q <= num[i]; q++)
			for (int j = 1000; j >= w[i]; j--){
				dp[j] = max(dp[j], dp[j - w[i]] + w[i]);
			}
	}
	cout << "Total=" << dp[1000];
}

希望有大佬可以给我指点一二,为什么原题解不对

标签:2000000,int,题解,P2347,砝码,NOIP1996,include,dp,mathrm
From: https://www.cnblogs.com/lgdxxs12138/p/18293466

相关文章

  • P3993 [BJOI2017] 同构 题解
    Description你有\(n\)个点,你可以在这\(n\)个点之间连无向边,两个点之间至多只能连一条边,也不允许连自环,问至多能连多少条边。但这个问题的答案显然是\(\frac{n(n-1)}{2}\)条。所以有一个额外的限制,要求这个图不存在非平凡的自同构。一个图\(G\)有非平凡的自同构定义为存......
  • [AHOI2013] 差异 题解
    后缀自动机维护子串公共后缀方便一点,所以直接倒序插入字符串即可。我们给所有前缀打上标记,然后跑树形\(dp\),设\(sum_i\)表示第\(i\)个点的子树内有多少个前缀,\(ans\)统计\(\sum\text{LCP}(T_i,T_j)\),则有:\[ans=\sum\limits_{i=1}^{id}\sum\limits_{j\inison}{sum}_j({......
  • 洛谷 P1853 投资的最大效益 蒟蒻题解
    洛谷P1853投资的最大效益蒟蒻题解题目背景约翰先生获得了一大笔遗产,他暂时还用不上这一笔钱,他决定进行投资以获得更大的效益。银行工作人员向他提供了多种债券,每一种债券都能在固定的投资后,提供稳定的年利息。当然,每一种债券的投资额是不同的,一般来说,投资越大,收益也越大,而......
  • Educational_round94题解
    Educational_round94题解A.StringSimilarity(构造+思维)解题思路原字符串长度为$2*n-1$,需要匹配的字符串一共有$n$个,要使所有字符串都得到匹配,即让构造的长度为$n$的字符串每一个位置都能匹配到一个。可得到$w_i=s_{2i}$题解#include<iostream>usingnamespacestd;chars......
  • 2024年06月CCF-GESP编程能力等级认证Python编程三级真题解析
    本文收录于专栏《Python等级认证CCF-GESP真题解析》,专栏总目录:点这里,订阅后可阅读专栏内所有文章。一、单选题(每题2分,共30分)第1题小杨父母带他到某培训机构给他报名参加CCF组织的GESP认证考试的第1级,那他可以选择的认证语言有几种?()A.1B.2C.3D.4答案:C第......
  • 题解 - 修剪草坪
    题目(in洛谷)或题目(inhszxoj)题目大意给定\(n\)个非负整数\(a_1\cdotsa_n\)。现在你可以选择其中若干个数,但不能有超过\(k\)个连续的数字被选择。求选出的数字的和最大。思路简析一个比较好的思路是反向思考:选择某些间隔小于等于\(k\)(相邻间隔为\(0\))的数字,求选......
  • Codeforces Round 956 (Div. 2) 部分题解A~C
    A.ArrayDivisibility题目大意构造长度为n的数组,满足:所有j的aj之和可以被k整除,其中j是k的倍数,k的取值为1~n。思路构造序列1->n即可满足条件。代码实现voidsolve(){  lln;cin>>n;  for(inti=1;i<=n;i++)cout<<i<<"";  cout<<"\n"......
  • joi2022_yo2_c 国土分割 (Land Division) 题解
    国土分割(LandDivision)推销我的洛谷博客。题意给定一个\(n\timesm\)的矩阵\(a\),你需要选择在横向或纵向分割至少一次,使得每个分割出来的小矩阵的\(a_{i,j}\)之和相等。数据范围\(1\leqslantn,m\leqslant50\)。\(1\leqslanta_{i,j}\leqslant10^5\)。思......
  • 题解 - 幻象迷宫
    题目in洛谷或题目inCF题目幻象迷宫可以认为是无限大的,不过它由若干个\(N\timesM\)的矩阵重复组成。矩阵中有的地方是道路,用\(\verb!.!\)表示;有的地方是墙,用\(\verb!#!\)表示。起始位置用\(\verb!S!\)表示。也就是对于迷宫中的一个点\((x,y)\),如果\((x\bmodn,y......
  • UVA12342 Tax Calculator 题解
    题目传送门题目大意题目描述某国所得税计算十分复杂。该国政府指定你制作一个自动计算所得税的程序。以下是该国计算所得税的规则:所得税免征额为180000180000......