南邮 OJ 1654 集训

集训

时间限制(普通/Java) :  1000 MS/ 3000 MS          运行内存限制 : 65536 KByte
总提交 : 87            测试通过 : 26 

比赛描述

南邮ACM暑期集训即将开始。由于放假后,学校的超市关闭营业,YM同学决定今天去超市购买一些商品。超市中一共有N(1<=N<=15)种商品,因为超市长时间没有进货,导致每种商品都仅剩下一件。第i种商品的价格为mi(1<=mi<=10^9),它的实用度为pi(0<=pi<=10000)。YM希望购买商品的总花费不超过M(0<=M<=10^9)。同时,超市今天正好有促销活动,只要购买商品的总花费不低于M1(0<=M1<=10^9),超市将赠送一件价格不超过M2(0<=m2<=10^9)的商品。YM希望购买的商品实用度的总和最大。



输入

多组输入数据。每组输入数据第一行有两个整数N和M。接下来N行,第i行有两个整数mi和pi,表示第i件商品的价格和实用度。最后一行有两个整数M1和M2。

输出

每组数据输出一行,在花费不超过M的情况下,购买的商品最大的实用度总和。

样例输入

3 3
1 2
2 4
3 5
3 2

样例输出

9

提示

 

题目来源

ym





/* AC 15MS Internet
#include 
#include 
#include 
using namespace std;


struct Item {
    int m;
    int p;
};


struct CmpItem {
    bool operator()(Item const &x, Item const &y) const {
        return x.p < y.p;
    }
};


Item g[17];


int N;
bool buy[20];
int restMoney;
int M, M1, M2;
int P;
int best;


int findGift() {
    int i;
    for (i = N - 1; i >= 0; --i) {
        if (!buy[i] && g[i].m <= M2) return g[i].p;
    }
    return 0;
}


void solve(int x) {
    if (x == N) {
        int cost = M - restMoney;
        if (cost >= M1) {
            best = max(best, P + findGift());
        } else {
            best = max(best, P);
        }
        return;
    }
    buy[x] = false;
    solve(x+1);
    if (restMoney < g[x].m) return;
    buy[x]=true;
    restMoney -= g[x].m;
    P += g[x].p;
    solve(x+1);
    restMoney += g[x].m;
    P -= g[x].p;
}


void input() {
    if (scanf("%d %d", &N, &M) != 2) exit(0);
    int i;
    for (i = 0; i < N; ++i) {
        scanf("%d %d", &(g[i].m), &(g[i].p));
    }
    scanf("%d %d", &M1, &M2);
}


void run() {
    sort(g, g + N, CmpItem());
    best = -2000000000;
    restMoney = M;
    P = 0;
    solve(0);
    printf("%d\n", best);
}


int main() {
    while(1) {
        input();
        run();
    }
	return 0;
}
*/








// 暴力枚举 93MS
#include
#include
using namespace std;


#define MAX_N 15
int m[MAX_N];
int p[MAX_N];


int main(){
	int N,M,M1,M2,i,k,cm,K,cp,mp;
	while(scanf("%d%d",&N,&M)==2){
		for(i=0;i			scanf("%d%d",m+i,p+i);
		}
		scanf("%d%d",&M1,&M2);
		K = 1<		mp = INT_MIN;
		for(k=0;k			cm = 0;
			cp = 0;
			for(i=0;i				if(k & (1<					cm += m[i];
					if(cm > M){
						break;
					}
					cp += p[i];
				}
			}
			if(cm <= M){
				if(cm >= M1){
					int more=0;
					for(i=0;i						if(!(k&(1<							more = p[i];
						}
					}
					cp += more;
				}
			}
			if(cp > mp){
				mp = cp;
			}
		}
		printf("%d\n",mp);
	}
}



你可能感兴趣的:(南邮,OJ)