zoukankan      html  css  js  c++  java
  • poj3260[USACO2006,Dec]The Fewest Coins最少找零

    题目链接:http://poj.org/problem?id=3260

    题目大意:


    题解:

    完全背包+多重背包

    预处理g[i]表示老板找i块钱时要花的最少纸币数。——完全背包

    f[i]表示'我'花i块钱时要用的最少纸币数。——多重背包(这个肯定要用二进制优化啦

    最后的答案就是min(f[i],g[t-i])。

    主要就是找钱的上限怎么找!一直WA!

    orz.看网上的证明其实并不是很懂。。其实想到做法就好了吧。~吧~

    #include<cstdio>
    #include<cstring>
    #include<cstdlib>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    #define maxn 101000
    #define inf 1000000000
    
    int c[110],v[110];
    int f[maxn],g[maxn];
    int mymin(int x,int y){return (x<y)?x:y;}
    int mymax(int x,int y){return (x>y)?x:y;}
    int main()
    {
    	//freopen("fewcoins.in","r",stdin);
    	//freopen("fewcoins.out","w",stdout);
    	int n,t,i,j,k,ans;
    	scanf("%d%d",&n,&t);
    	for (i=1;i<=n;i++)
    	 scanf("%d",&v[i]);
    	int sum=0,mx=0;
    	for (i=1;i<=n;i++)
    	{
    		scanf("%d",&c[i]);
    		sum+=c[i]*v[i];
    		mx=mymax(mx,v[i]*v[i]);
    	}//t+mx当找钱的上限
    	if (sum<t) {printf("-1
    ");return 0;}
    	memset(g,63,sizeof(g));
    	memset(f,63,sizeof(f));
    	g[0]=0;f[0]=0;
    	for (i=1;i<=n;i++)
    	 for (j=v[i];j<=t+mx;j++)
    	  g[j]=mymin(g[j],g[j-v[i]]+1);
    	for (i=1;i<=n;i++)
    	{
    		for (j=1;j<=c[i];j*=2)
    		{
    			for (k=t+mx;k>=j*v[i];k--)
    			 f[k]=mymin(f[k],f[k-j*v[i]]+j);
    			c[i]-=j;
    		}
    		if (c[i]!=0)
    		 for (k=t+mx;k>=c[i]*v[i];k--)
    		  f[k]=mymin(f[k],f[k-c[i]*v[i]]+c[i]);
    	}ans=inf;
    	for (i=t;i<=t+mx;i++)
    	 ans=mymin(f[i]+g[i-t],ans);
    	if (ans==inf) printf("-1
    ");
    	else printf("%d
    ",ans);
    	return 0;
    }


  • 相关阅读:
    一个自动化测试工具 UI Recorder
    通俗理解http2.0
    IE 问题集合
    webpack
    性能工具集合
    网络 问题
    css命名规范
    ajax 总结
    CSS深入理解学习笔记之relative
    jQuery插件开发通用框架
  • 原文地址:https://www.cnblogs.com/Euryale-Rose/p/6527854.html
Copyright © 2011-2022 走看看