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;
    }
    
  • 相关阅读:
    【python】requests库
    pycharm新建项目时选择virtualenv的说明
    cookie、session、token
    读写锁--DEMO
    锁降级--防止线程安全问题
    mysql-left join
    index-document-shard
    ES-常见搜索方式
    SpringBoot在自定义类中调用service层等Spring其他层
    mongodb crud
  • 原文地址:https://www.cnblogs.com/ShineEternal/p/10834287.html
Copyright © 2011-2022 走看看