zoukankan      html  css  js  c++  java
  • NOIp2018 TG day1 T2暨洛谷P5020 货币系统:题解

    题目链接:https://www.luogu.org/problemnew/show/P5020

    这道题感觉比较水啊,身为普及组蒟蒻都不费力的做出来了,而且数据范围应该还能大一些,n起码几万几十万都不一定T。求过~

    分析:

    本题是类似完全背包问题,分析样例我们可以得出结论:一种面值的货币如果可以由此系统中的其他货币组合而来,那么它就是可有可无的。

    由此我们分析:不妨只在一个系统中做出删减,删掉尽可能多的面值不就行了吗?

    对于每个数,我们判断其能否组合出,就成了典型的背包问题。

    我们设f[i]f[i]表示i是否可以在题目给出的系统中被表示出来。那么每一次就可以转移为:

    f[j]=f[j]f[ja[i]]f[j]=f[j]||f[j-a[i]]

    即当前如果能被ja[i]j-a[i]或自己在之前已经被其他的数字表示,都算为可有可无的数,这样再每次判断a[j]a[j]是否被表示来觉得是否删掉它就行了
    下面是代码,附注释。

    代码:

    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<cmath>
    using namespace std;
    int f[25005],a[105];//看这数组小的不可思议。。。
    int main()
    {
    	int T;
    	scanf("%d",&T);
    	while(T--)//这种读入多组数据的方法比较方便。
    	{
    		int n;
    		scanf("%d",&n);
    		for(int i=1;i<=n;i++)
    		{
    			scanf("%d",&a[i]);
    		}
    		int ans=n;
    		sort(a+1,a+n+1);//从小到大排序
    		memset(f,0,sizeof(f));//每次清空
    		f[0]=1;
    		for(int j=1;j<=n;j++)
    		{
    			if(f[a[j]]==1)
    			{
    				ans--;
    				continue;
    			}
    			for(int k=a[j];k<=a[n];k++)
    			{
    				f[k]=f[k]||f[k-a[j]];
    			}
    		}
    		printf("%d
    ",ans);
    	}
    	return 0;
    }
    
  • 相关阅读:
    .net 中文显示乱码问题(Chinese display with messy code)
    Compare the value of entity field.
    人见人爱A^B 题解
    人见人爱A-B 题解
    全局变量
    第39级台阶 题解
    马虎的算式 题解
    做题技巧
    inline用法
    queue函数用法
  • 原文地址:https://www.cnblogs.com/vercont/p/10210044.html
Copyright © 2011-2022 走看看