• 题解 JSOI2010 找零钱的洁癖


    题解 JSOI2010 找零钱的洁癖

    题面

    BZOJ

    个人体会

    van全没有思路...

    只能去看题解...

    还是个bfs+贪心

    不管怎样竟然乱搞过了...

    听M_sea小姐姐说她有更正经的做法(线性规划,网络流)?

    解析

    就是求最少的数加加减减得到(X).

    考虑一波暴搜...

    没了

    开个map存一下当前的数经过没有.

    最后和贪心比一下.

    改错经历

    一开始手写了一个Hash.

    结果不知道为什么伪了...

    然后用map过了...

    另外还有数组开小(毕竟是搜索),循环边界写错导致RE的问题.

    code

    #include <iostream>
    #include <stdio.h>
    #include <cstring>
    #include <algorithm>
    #include <map>
    #define ll long long
    #define filein(a) freopen(a".cpp","r",stdin)
    #define fileout(a) freopen(a".cpp","w",stdout);
    using namespace std;
    
    inline ll read(){
    	ll sum=0,f=1;char c=getchar();
    	while((c<'0'||c>'9')&&c!=EOF){if(c=='-') f=-1;c=getchar();}
    	while(c>='0'&&c<='9'&&c!=EOF){sum=sum*10+c-'0';c=getchar();}
    	return sum*f;
    }
    
    const int N=1000003;
    const int INF=0x7FFFFFFF;
    int n;
    ll X,c[N],s[N],a[N];
    map<ll,bool> mp;
    
    inline ll greedy(){
    	ll ret=0,sum=X;
    	for(int i=n;i;i--){
    		if(!a[i]) continue;
    		ret+=sum/a[i];
    		sum-=sum/a[i]*a[i];
    	}
    	return sum? INF:ret;
    }
    
    inline ll bfs(){
    	int hd=0,tl=1;
    	s[1]=c[1]=0;
    	while(hd<tl){
    		hd++;
    		for(int i=1;i<=n;i++){
    			tl++;if(tl==N-22) return INF;
    			s[tl]=s[hd]+1;
    			c[tl]=c[hd]<X? c[hd]+a[i]:c[hd]-a[i];
    			if(c[tl]==X) return s[tl];
    			if(mp.count(c[tl])){tl--;continue;}
    			mp[c[tl]]=1;
    		}
    	}
    	return INF;
    }
    
    signed main(){
    	X=read();
    	while(scanf("%lld",&a[++n])!=EOF);
    	sort(a+1,a+n+1);
    	if(!X) puts("0");
    	else printf("%lld
    ",min(greedy(),bfs()));
    	return 0;
    }
    
  • 相关阅读:
    文件操作
    MFC
    MFC
    MFC
    MFC
    大陆居民身份证验证方法(java)
    java validator的原理与使用
    解析搜狗词库(python)
    ICTCLAS改进的java版分词软件
    mvn打包
  • 原文地址:https://www.cnblogs.com/permzf/p/12243747.html
Copyright © 2020-2023  润新知