zoukankan      html  css  js  c++  java
  • ZOJ 3812 We Need Medicine(dp、背包、状态压缩、路径记录)

    参考:http://blog.csdn.net/qian99/article/details/39138329

    参考的链接里说明得很好,注释也很好。。。thanks for sharing

    朴素的想法不难,dp[i][j][k]类似背包做法即可。

    但朴素思想复杂度过高。

    这里主要是用到 dif 那个变量,只枚举新增的集合。

    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    #include <cmath>
    #include <vector>
    #include <set>
    #include <queue>
    #include <map>
    using namespace std;
    
    #define MP make_pair
    #define ll long long
    #define inf 0x3f3f3f3f
    #define maxn 100010
    #define maxm 200010
    
    ll sta[200010];
    int ans[55][200010];
    map<ll,int>mp;
    int a[410],b[410];
    int main(){
    	for(int i=0;i<=50;++i) mp.insert(MP(1ll<<i,i));
    	int t,n,q;
    	scanf("%d",&t);
    	while(t--){
    		scanf("%d%d",&n,&q);
    		memset(sta,0,sizeof(sta));
    		memset(ans,-1,sizeof(ans));
    		sta[0] = 1;
    		for(int i=1;i<=n;++i){
    			scanf("%d%d",a+i,b+i);
    			for(int j=200000;j>=b[i];--j){
    				ll st = sta[j];
    				sta[j] |= (sta[j-b[i]]<<a[i]) & ((1ll<<52)-1);
    				ll dif = st^sta[j];
    				while(dif){
    					ll low = dif&(-dif);
    					int cnt = mp[low];
    					ans[cnt][j] = i;
    					dif -= low;
    				}
    			}
    		}
    		for(int i=0;i<q;++i){
    			int mi,si;
    			scanf("%d%d",&mi,&si);
    			if(ans[mi][si]==-1) puts("No solution!");
    			else {
    				int idx = ans[mi][si];
    				printf("%d",idx);
    				mi -= a[idx];
    				si -= b[idx];
    				while(mi){
    					int idx = ans[mi][si];
    					printf(" %d",idx);
    					mi -= a[idx];
    					si -= b[idx];
    				}
    				puts("");
    			}
    		}
    	}
        return 0;
    }
    
  • 相关阅读:
    对象与引用
    聊天室小程序
    tcp程序设计--客户端获取服务器输入输出流
    线程小例子--进度条
    线程小例子--控制输出
    ngnix反向代理
    使用vuex管理数据
    vue列表到详情页的实现
    vue-实现一个购物车结算页面
    localstorage本地存储的应用
  • 原文地址:https://www.cnblogs.com/nextbin/p/3964893.html
Copyright © 2011-2022 走看看