(ssl 2295)暗黑破坏神

来源:互联网 发布:linux close 头文件 编辑:程序博客网 时间:2024/04/28 22:49

Description

无聊中的小x玩起了Diablo I...

游戏的主人公有n个魔法

每个魔法分为若干个等级,第i个魔法有p[i]个等级(不包括0)

每个魔法的每个等级都有一个效果值,一个j级的i种魔法的效果值为w[i][j]

魔法升一级需要一本相应的魔法书

购买魔法书需要金币,第i个魔法的魔法书价格为c[i]

而小x只有m个金币(好孩子不用修改器)

你的任务就是帮助小x决定如何购买魔法书才能使所有魔法的效果值之和最大

开始时所有魔法为0级 效果值为0

Input

第一行 用空格隔开的两个整数n(0<n<=100) <br="" m(0<m<="500)">
以下n行 描述n个魔法

第i+1行描述 第i个魔法 格式如下(0<p[i]<=50, <br="" 0<c[i]<="10)">
c[i] p[i] w[i][1] w[i][2] ... w[i][p[i]]

Output

第一行输出一个整数,即最大效果

Sample Input

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

Sample Output

1110

3

分析:01背包,并输出其中一种方案(后面的才是重点)

  • #include <cstdio>#include <algorithm>using namespace std;int n,m,c[101],s[101],b[101][501],w[101][501],f[101][501],ans[101][501];void print(int x,int y){if (!x) return;print(x-1,y-b[x][y]*c[x]); //回去找printf("%d\n",b[x][y]); //输出}int main(){scanf("%d%d",&n,&m);for (int i=1;i<=n;i++){scanf("%d%d",&c[i],&s[i]);
  •         for (int j=1;j<=s[i];j++) scanf("%d",&w[i][j]);}        for (int i=1;i<=n;i++)for (int j=0;j<=m;j++) //01背包(二维顺推)for (int k=0;k<=s[i];k++) //个数if (j>=k*c[i]&&f[i-1][j-k*c[i]]+w[i][k]>f[i][j])  //最大吗?f[i][j]=f[i-1][j-k*c[i]]+w[i][k],b[i][j]=k;  //b:方案
  •         int max=-0x7fffffff,y;for (int i=0;i<=m;i++) if (f[n][i]>max){max=f[n][i]; y=i;}//二维要找最大值printf("%d\n",f[n][y]);print(n,y); //这才是重点return 0;}

原创粉丝点击