暗黑破坏神

来源:互联网 发布:柳青 乳腺癌 知乎 编辑:程序博客网 时间:2024/05/17 01:33

Problem Description

游戏的主人公有n(0<n<=100)个魔法,每个魔法分为若干个等级,第i个魔法有p[i](0<p[i]<=50)个等级(不包括0),每个魔法的每个等级都有一个效果值,一个j级的i种魔法的效果值为w[i,j],魔法升一级需要一本相应的魔法书,购买魔法书需要金币,第i个魔法的魔法书价格为c[i](0<c[i]<=10),而小x只有m(0<m<=500)个金币。你的任务就是帮助小x决定如何购买魔法书才能使所有魔法的效果值之和最大,开始时所有魔法为0级,效果值为0。

Input

输入有多组数据,每组数据第1行为用空格隔开的两个整数n和m。以下n个魔法,第i+1行描述第i个魔法,格式如下:
c[i] p[i] w[i,1] w[i,2]...w[i,p[i]]

Output

对于每组数据先输出一个整数,即最大效果值,以后n行输出你的方案:
第i+1行有一个整数v[i]表示你决定把第i个魔法学到v[i]级;如果有多解,输出花费金币最少的一组;如果还有多解,输出任意一组。

Sample Input

3 101 3 1 2 22 3 2 4 63 3 2 1 10

Sample Output

11103
//关键字: 背包(带路径分组背包);
//标程:
#include<iostream>#include<cstdio>#include<cstring>using namespace std;int dp[101][505], p[105], v[105], ans[105];int w[101][55], mark[105][505];int main(){//      freopen("a.txt","r",stdin);        int item, volume, i, j, k;while(cin >> item >> volume){memset(dp,0,sizeof(dp));memset(mark,0,sizeof(mark));memset(w,0,sizeof(w));for(i = 1; i <= item; i ++){cin >> v[i] >> p[i];for(j = 1; j <= p[i]; j ++)cin >> w[i][j];}int max = -1; for(i = 1; i <= item; i ++){for(j = 1; j <= volume; j ++){dp[i][j] = dp[i-1][j];for(k = 1; k <= p[i]; k ++){if(k*v[i] <= j){    if(dp[i-1][j-k * v[i]] + w[i][k] > dp[i][j]){dp[i][j] = dp[i-1][j-k*v[i]] + w[i][k];                                                        mark[i][j] = k;}}}}int t = 0;for (j = volume; j >= 1; j--)        {              for (i = item; i >= 1; i--)              {                     if (dp[i][j] >= max)                     {                            k = j;                            t = i;                            max = dp[i][j];                     }              }       }       memset(ans, 0, sizeof(ans));       j = k;        for (i = t; i >= 1; i--)       {              ans[i] = mark[i][j];              j = j - v[i] * ans[i];       }       cout << max << endl;       for (i = 1; i <= item; i++)             cout << ans[i] << endl;}return 0;}
0 0
原创粉丝点击