zoukankan      html  css  js  c++  java
  • P2851 [USACO06DEC]The Fewest Coins G

    Jisoo

    显然找硬币和付钱是两个过程

    然而最多给多少钱呢

    有应该找最多多多少呢?

    方案一

    时间绰绰有余,我们开的大一点

    证明

    找钱的数量不会超过(V_{max}^2)

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    using namespace std;
    int T;
    int n;
    int v[105];
    int f1[34405];
    int f2[24405]; 
    int c[105];
    int maxx;
    int ans;
    int sum;
    int main(){
    	scanf("%d%d",&n,&T);
    	for(int i=1;i<=n;++i){
    		scanf("%d",&v[i]);
    	}
    	for(int i=1;i<=n;++i){
    		scanf("%d",&c[i]);
    	}
    	memset(f2,0x3f,sizeof(f2));
    	memset(f1,0x3f,sizeof(f1));
    	maxx=f2[0];
    	f2[0]=f1[0]=0;
    	for(int i=1;i<=15000;++i){
    		for(int j=1;j<=n;++j){
    			if(i>=v[j]){
    				f2[i]=min(f2[i],f2[i-v[j]]+1);
    			}
    		}
    	}
    	for(int i=1;i<=n;++i){
    		for(int j=1;j<=c[i];j<<=1){
    			for(int z=T+15000;z>=j*v[i];--z){
    				f1[z]=min(f1[z],f1[z-j*v[i]]+j);
    			}
    			c[i]-=j;
    		}
    		if(c[i]){
    			for(int z=T+15000;z>=c[i]*v[i];--z){
    				f1[z]=min(f1[z],f1[z-c[i]*v[i]]+c[i]);
    			}
    		}
    	}
    	ans=maxx;
    	for(int i=0;i<=15000;++i){
    		ans=min(ans,f1[i+T]+f2[i]);
    	}
    	if(ans==maxx)
    	cout<<-1;
    	else
    	cout<<ans;
    	return 0;
    } 
    
  • 相关阅读:
    jvm详解
    JVM堆外内存
    Guava基本使用
    Mondrian开源OLAP引擎详解
    Java8新特性简明教程
    TCP/IP协议三次握手和四次挥手详解
    Go 方法与函数区别
    Go 通道 Chan 详解
    kylin详细介绍
    计数排序
  • 原文地址:https://www.cnblogs.com/For-Miku/p/15270106.html
Copyright © 2011-2022 走看看