zoukankan      html  css  js  c++  java
  • P3423 [POI2005]BAN-Bank Notes

    Miku

    仍然是要优化的,但是输出方案是非常恶心的

    一维爆炸,以下为二进制优化做法

    关键是如果最后到着找方案的话,就比如说样例

    5的最少方法就是一个5,但是因为dp的顺序是逆序。会把10指向5,然后5指向0

    、??,但是只有一个啊。所以不能倒序

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    using namespace std;
    const int maxn=200001;
    int cnt;
    int num[maxn],ca[maxn];
    int num1[maxn],ca1[maxn];
    int dp[maxn];
    int k;
    int aimm,n;
    int ans[maxn];
    int ord[maxn];
    int used[maxn];
    int sum;
    bool tu[3010][20010];
    int main(){
    	memset(dp,0x7f,sizeof(dp));
    	dp[0]=0;
    	scanf("%d",&n);
    	for(int i=1;i<=n;++i){
    		scanf("%d",&ca[i]);
    		ord[ca[i]]=i;
    	}
    	for(int i=1;i<=n;++i){
    		scanf("%d",&num[i]);
    	}
    	scanf("%d",&aimm);
    	for(int i=1;i<=n;++i){
    		for(int j=1;j<=num[i];j=j<<1){
    			cnt++;
    			num1[cnt]=j;
    			ca1[cnt]=j*ca[i];
    			num[i]-=j;
    			ord[cnt]=i;
    		}
    		if(num[i]){
    			cnt++;
    			num1[cnt]=num[i];
    			ca1[cnt]=num[i]*ca[i];
    			ord[cnt]=i;
    		}
    	}
    	for(int i=1;i<=cnt;++i){
    		for(int j=aimm;j>=ca1[i];--j){
    			if(dp[j]>dp[j-ca1[i]]+num1[i]){
    				dp[j]=dp[j-ca1[i]]+num1[i];
    				tu[i][j]=1; 
    			}
    		}
    	} 
    	cout<<dp[aimm]<<endl;
    	while(aimm){
    		while(!tu[cnt][aimm]&&cnt) --cnt;//是谁变成了aimm?
    		//当然,肯定是后面的变前面的 
    		aimm-=ca1[cnt];//去掉贡献 
    		ans[ord[cnt]]+=num1[cnt];
    		--cnt;//接着找 
    	}
    	for(int i=1;i<=n;++i){
    		cout<<ans[i]<<" ";
    	}
    	return 0;
    } 
    
  • 相关阅读:
    TestNG系列(四)TestNG监听器
    SpringBoot中Conditional的条件
    TCP的四次挥手与三次握手
    [Lamada] lamda流操作
    [Spring] 封装request 自定义添加parameter
    AES加密Demo
    [转]数据库软件架构,到底要设计些什么
    [正则表达式]
    [mysql] 查询配置文件读取位置和顺序
    [MySQL]错误日志
  • 原文地址:https://www.cnblogs.com/For-Miku/p/13434579.html
Copyright © 2011-2022 走看看