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

    [POI2005]BAN-Bank Notes

    problem:

    经典的多重背包问题。要求输出方案

    data range:

    正常

    solution:

    问题本身不难。主要在于输出方案。
    我采用的是二进制优化多重背包。
    如果不用任何辅助数组直接做就是这样:

    void find(int x,int pos)
    {
    	if(!x)return;
    	int u=0;
    	for(int i=pos;i;--i)
    		if(f[pos-1][x-a[i-1].se]+a[i-1].fi==f[pos][x])
    		{
    			u=i,cnt[a[i-1].se/a[i-1].fi]+=a[i-1].fi;
    			break;
    		}
    	find(x-a[u-1].se,u-1);
    }
    

    然而这道题十分不友善卡空间,全部MLE了
    那么我们对f用滚动数组优化空间,然后定义(flag_{i,j})表示(f_{i,j})在此处是否发生转移
    然后类似套用就可以了---

    space time complexity:

    time&space:(O(NMlogM))

    code:

    #include<bits/stdc++.h>
    #define pb push_back
    #define mp make_pair
    #define se second
    #define fi first
    using namespace std;
    typedef pair<int,int> pii;
    const int N=205,M=2e4+5;
    int n,k;
    int b[N],f[M],cnt[M];
    bool flag[N<<4][M];
    vector<pii>a;
    void find(int x,int pos)
    {
    	if(!x)return;
    	int u=0;
    	for(int i=pos;i;--i)
    		if(flag[i][x])
    		{
    			u=i,cnt[a[i-1].se/a[i-1].fi]+=a[i-1].fi;
    			break;
    		}
    	find(x-a[u-1].se,u-1);
    }
    int main()
    {
    	scanf("%d",&n);
    	for(int i=1;i<=n;++i)scanf("%d",b+i);
    	for(int i=1;i<=n;++i)
    	{
    		int c;scanf("%d",&c);
    		for(int j=0;c;++j)
    		{
    			int cnt=1<<j;
    			if(c<cnt)a.pb(mp(c,b[i]*c)),c=0;
    			else a.pb(mp(cnt,b[i]*cnt)),c-=cnt;
    		}
    	}
    	scanf("%d",&k);
    	memset(f,120,sizeof(f));
    	f[0]=0;
    	for(int i=1;i<=a.size();++i)
    		for(int j=k;j>=a[i-1].se;--j)
    			if(f[j-a[i-1].se]+a[i-1].fi<f[j])
    				f[j]=f[j-a[i-1].se]+a[i-1].fi,flag[i][j]=true;
    	cout<<f[k]<<endl;
    	find(k,a.size());
    	for(int i=1;i<=n;++i)printf("%d ",cnt[b[i]]);
    	return 0;
    }
    
  • 相关阅读:
    第一阶段冲刺第七天
    第一次冲刺第六天
    第十一周学习进度条
    第一阶段冲刺第五天
    《我们应该怎样做需求分析》阅读笔记
    个人总结
    第二阶段个人总结十
    第二阶段个人总结九
    第二阶段个人总结八
    第二阶段个人总结七
  • 原文地址:https://www.cnblogs.com/zmyzmy/p/13746834.html
Copyright © 2011-2022 走看看