poj 1170 Shopping Offers

IOI的題目很有殺傷力
有n中編號的物品,每種物品有自己的單價,在促銷活動中,第j件物品可以和指定的其他第ni件物品(1<=i<=5)物品進行組合,組合之後,有對應的促銷價格。現在求最小的價格。
1.計算當前最小价格,第ni(1<=i<=5)要麼不與其他物品進行組合促銷,要麼在可以組合促銷的前提下,進行促銷。即爲當前最優解,顯然需要搜索+回溯
2.用六維數組dp[i][j][k][l][m][n](i,j,k,l,m,分別代表5種物品的數量,n(1<=n<=s)表示採用第n中組合的促銷優惠)表示第n種促銷優惠中的購買指定物品的最小价格。

#include<iostream>
#include<string.h>
#include<math.h>
#include<fstream>
#include<algorithm>
#include<stdio.h>
#include<queue>
#include<vector> 

using namespace std;
#define MAX 1<<30; 
#define min(a,b) ((a)<(b)?(a):(b))
#define max(a,b) ((a)>(b)?(a):(b))

typedef struct str_a { int r[5], price; } sale;

int dyna[6][6][6][6][6][101];
int uid[1010], a[5], price[5], mr = 0;
sale list[101]; int s;

int search (int id, int n)
{
    int i, j, ans = MAX;
    if (id >= s)
    {
        for (i = 0; i < 5; i++)
            if (a[i] > 0) n += a[i] * price[i];
        return n;
    }
    else if (dyna[max(a[0], 0)][max(a[1], 0)][max(a[2], 0)][max(a[3], 0)][max(a[4], 0)][id] >= 0)
        return dyna[max(a[0], 0)][max(a[1], 0)][max(a[2], 0)][max(a[3], 0)][max(a[4], 0)][id] + n;
    else
    {
        for (i = 0; i <= 5; i++)
        {
            for (j = 0; j < 5; j++) a[j] -= (list[id].r[j] * i);
            ans = min(ans, search(id + 1, list[id].price * i));
            for (j = 0; j < 5; j++) a[j] += (list[id].r[j] * i);
        }
        dyna[max(a[0], 0)][max(a[1], 0)][max(a[2], 0)][max(a[3], 0)][max(a[4], 0)][id] = ans;
        return ans + n;
    }
}

int main ()
{
    //freopen("data_1170","r",stdin);
    int i, j, n, id, amount, pri, g;
    memset(dyna, -1, sizeof(dyna));
    memset(a, 0, sizeof(a));
    memset(price, 0, sizeof(price));
    scanf("%d", &n);
    for (i = 0; i < n; i++)
    {
        scanf("%d %d %d", &id, &amount, &pri);
        uid[id] = i;
        a[i] = amount;
        price[i] = pri;
    }
    scanf("%d", &s);
    for (i = 0; i < s; i++)
    {
        for (j = 0; j < 5; j++)
            list[i].r[j] = 0;
        scanf("%d", &g);
        for (j = 0; j < g; j++)
        {
            scanf("%d %d", &id, &amount);
            list[i].r[uid[id]] = amount;
        }
        scanf("%d", &list[i].price);
    }
    printf("%d\n", search(0, 0));
    return 0;
}

這裏寫圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章