ZOJ--3631--Watashi's BG【枚举】

链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=4777

题意:有n天,告诉你每天的花费,别人给你一笔资金m,你自己也有一部分资金(可以假设花不完),每天只能花自己的钱或者花资金m中的钱,不能混着花,问m最多能花多少?

思路:考虑到数据比较小,n最多只有30,可以用枚举来做,枚举每天花m或者不花m,二进制枚举,复杂度2^30。这样复杂度要超时的,土豪说可以分两部分枚举,把结果存入两个数组,然后这两个数组结果再合并,复杂度n^2,这样二进制枚举最多是两个2^15,大大缩短了时间复杂度。

后来我又用dfs写了一遍,果断T,看了别人的代码,有个剪枝很关键,当前已使用的资金与所有还未使用的资金相加如果小于等于已得到的最大值,则剪枝。

二进制枚举代码

#include<cstring>
#include<string>
#include<fstream>
#include<iostream>
#include<iomanip>
#include<cstdio>
#include<cctype>
#include<algorithm>
#include<queue>
#include<map>
#include<set>
#include<vector>
#include<stack>
#include<ctime>
#include<cstdlib>
#include<functional>
#include<cmath>
using namespace std;
#define PI acos(-1.0)
#define MAXN 5000100
#define eps 1e-7
#define INF 0x7FFFFFFF
#define LLINF 0x7FFFFFFFFFFFFFFF
#define seed 131
#define MOD 1000000007
#define ll long long
#define ull unsigned ll
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1

int a[200010],b[200010],va[40],vb[40];
int main(){
    int i,j;
    int n,m;
    int la,lb,cnta,cntb,ans;
    while(scanf("%d%d",&n,&m)!=EOF){
        la = lb = cnta = cntb = ans = 0;
        for(i=0;i<n/2;i++){
            scanf("%d",&va[i]);
            la++;
        }
        for(i=n/2;i<n;i++){
            scanf("%d",&vb[i-n/2]);
            lb++;
        }
        int l = (1<<la);
        for(i=0;i<l;i++){
            int sum = 0;
            for(j=0;j<la;j++){
                if(i&(1<<j)){
                    sum += va[j];
                }
            }
            if(sum<=m){
                a[cnta++] = sum;
                ans = max(sum,ans);
            }
        }
        l = (1<<lb);
        for(i=0;i<l;i++){
            int sum = 0;
            for(j=0;j<lb;j++){
                if(i&(1<<j)){
                    sum += vb[j];
                }
            }
            if(sum<=m){
                b[cntb++] = sum;
                ans = max(sum,ans);
            }
        }
        sort(a,a+cnta);
        sort(b,b+cntb);
        if(ans==m){
            printf("%d\n",ans);
            continue;
        }
        for(i=cnta-1;i>=0;i--){
            for(j=cntb-1;j>=0;j--){
                if(a[i]+b[j]<=m){
                    ans = max(ans,a[i]+b[j]);
                    break;
                }
            }
        }
        printf("%d\n",ans);
    }
    return 0;
}

DFS代码

#include<cstring>
#include<string>
#include<fstream>
#include<iostream>
#include<iomanip>
#include<cstdio>
#include<cctype>
#include<algorithm>
#include<queue>
#include<map>
#include<set>
#include<vector>
#include<stack>
#include<ctime>
#include<cstdlib>
#include<functional>
#include<cmath>
using namespace std;
#define PI acos(-1.0)
#define MAXN 5000100
#define eps 1e-7
#define INF 0x7FFFFFFF
#define LLINF 0x7FFFFFFFFFFFFFFF
#define seed 131
#define MOD 1000000007
#define ll long long
#define ull unsigned ll
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1

int a[40],jz[40];
int n,m,maxm;
void dfs(int step,int cnt){
    if(cnt>m)   return ;
    maxm = max(maxm,cnt);
    if(step<1) return ;
    if(cnt+jz[step]<=maxm)  return ;    //防TLE剪枝
    dfs(step-1,cnt);
    dfs(step-1,cnt+a[step]);
}
int main(){
    int i,j;
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        for(i=1;i<=n;i++){
            scanf("%d",&a[i]);
        }
        jz[0] = 0;
        for(i=1;i<=n;i++)    jz[i] = jz[i-1] + a[i];
        maxm = 0;
        dfs(n,0);
        printf("%d\n",maxm);
    }
    return 0;
}

ZOJ--3631--Watashi's BG【枚举】

时间: 2025-01-04 16:37:03

ZOJ--3631--Watashi's BG【枚举】的相关文章

ZOJ 3631 Watashi&#39;s BG DFS

J - Watashi's BG Time Limit:3000MS     Memory Limit:65536KB     64bit IO Format:%lld & %llu Submit Status Practice ZOJ 3631 Appoint description: Description Watashi is the couch of ZJU-ICPC Team and he is very kind hearted. In ZJU-ICPC summer trainin

ZOJ 3631 Watashi&#39;s BG(dp+dfs)

题意:一共要吃n顿饭 公款m元 如果公款大于等于饭局所需费用 就全用公款 如果小于就自费 求最后能用的公款为多少 思路: dfs(i - 1, val + dp[i]); dfs(i - 1, val); #include <stdio.h> #include <string.h> #include <stdlib.h> #include <algorithm> using namespace std; int dp[50]; int n, m; int a

dfs+剪枝 zoj 3631

X - Watashi's BG Time Limit:3000MS     Memory Limit:65536KB     64bit IO Format:%lld & %llu Submit Status Practice ZOJ 3631 Appoint description:  System Crawler  (2015-04-15) Description Watashi is the couch of ZJU-ICPC Team and he is very kind heart

Zoj 3088 Easter Holidays SPFA+枚举

其实就是枚举最高点和起点,然后以最高点为源点在两张图上分别做spfa.一遍最短路,一遍最长路. 暴露出来的问题:思维不够清晰,代码能力还不够 #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> #include <climits> #include <string> #include <iostream> #include &

zoj 1008 Gnome Tetravex (dfs+枚举)

Gnome Tetravex Time Limit: 10 Seconds      Memory Limit: 32768 KB Hart is engaged in playing an interesting game, Gnome Tetravex, these days. In the game, at the beginning, the player is given n*n squares. Each square is divided into four triangles m

ZOJ 3693 Happy Great BG(卡精度)

Description The summer training of ZJU ICPC in July is about to end. To celebrate this great and happy day, the coaches of ZJU ICPC Team Naviand Fancy decided to BG everyone! Beside the two coaches, there are N participants. Those participants are di

ZOJ 3693 Happy Great BG

Happy Great BG Time Limit: 2 Seconds      Memory Limit: 65536 KB The summer training of ZJU ICPC in July is about to end. To celebrate this great and happy day, the coaches of ZJU ICPC Team Navi and Fancy decided to BG everyone! Beside the two coache

ZOJ 3987 Numbers(Java枚举)

http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3987 题意:给出一个数n,现在要将它分为m个数,这m个数相加起来必须等于n,并且要使得这m个数的或值最小. 思路: 从二进制的角度分析,如果这m个数中有一个数某一位为1,那么最后或起来这一位肯定是为1的,所以如果某一位为1了,那么我们尽量就让其余位也等于1. 所以我们从最高位开始枚举,看看这一位是否需要为1,如果需要为1的话,那么剩下的几个数也尽量让这一位等于1. 1 i

ZOJ Monthly, July 2012

zoj 3622.Magic Number   水题 先找规律生成区间[1,1<<32-1]内的所有Magic Number,计算出来只有40多个,然后就随便YY了. void init() { int a[5] = { 1,2,5,25,125 }; ll Max = (1ll<<32)-1; for(ll tmp =1; tmp<=Max; tmp *=10) { for(int i=0; i<5; ++i){ ll t = tmp * a[i]; if(t>

(01背包搜索) zoj 3013

Watashi's BG Time Limit: 3 Seconds      Memory Limit: 65536 KB Watashi is the couch of ZJU-ICPC Team and he is very kind hearted. In ZJU-ICPC summer training camp, students are divided into several groups and each day one of the groups will design so