您的位置:首页 > 其它

南邮 OJ 1654 集训

2015-08-06 10:27 218 查看

集训

时间限制(普通/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 <algorithm>
#include <cstdio>
#include <cstdlib>
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();
    }
<span style="white-space:pre">	</span>return 0;
}
*/

// 暴力枚举 93MS
#include<iostream>
#include<algorithm>
using namespace std;

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

int main(){
<span style="white-space:pre">	</span>int N,M,M1,M2,i,k,cm,K,cp,mp;
<span style="white-space:pre">	</span>while(scanf("%d%d",&N,&M)==2){
<span style="white-space:pre">		</span>for(i=0;i<N;i++){
<span style="white-space:pre">			</span>scanf("%d%d",m+i,p+i);
<span style="white-space:pre">		</span>}
<span style="white-space:pre">		</span>scanf("%d%d",&M1,&M2);
<span style="white-space:pre">		</span>K = 1<<N;
<span style="white-space:pre">		</span>mp = INT_MIN;
<span style="white-space:pre">		</span>for(k=0;k<K;k++){
<span style="white-space:pre">			</span>cm = 0;
<span style="white-space:pre">			</span>cp = 0;
<span style="white-space:pre">			</span>for(i=0;i<N;i++){
<span style="white-space:pre">				</span>if(k & (1<<i)){
<span style="white-space:pre">					</span>cm += m[i];
<span style="white-space:pre">					</span>if(cm > M){
<span style="white-space:pre">						</span>break;
<span style="white-space:pre">					</span>}
<span style="white-space:pre">					</span>cp += p[i];
<span style="white-space:pre">				</span>}
<span style="white-space:pre">			</span>}
<span style="white-space:pre">			</span>if(cm <= M){
<span style="white-space:pre">				</span>if(cm >= M1){
<span style="white-space:pre">					</span>int more=0;
<span style="white-space:pre">					</span>for(i=0;i<N;i++){
<span style="white-space:pre">						</span>if(!(k&(1<<i)) && m[i]<=M2 && more<p[i]){
<span style="white-space:pre">							</span>more = p[i];
<span style="white-space:pre">						</span>}
<span style="white-space:pre">					</span>}
<span style="white-space:pre">					</span>cp += more;
<span style="white-space:pre">				</span>}
<span style="white-space:pre">			</span>}
<span style="white-space:pre">			</span>if(cp > mp){
<span style="white-space:pre">				</span>mp = cp;
<span style="white-space:pre">			</span>}
<span style="white-space:pre">		</span>}
<span style="white-space:pre">		</span>printf("%d\n",mp);
<span style="white-space:pre">	</span>}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: