第一行输入两个整数
代表预算、查询到的物品总数。
此后
行,第
行输入三个整数
代表第
件物品的价格、重要度、主件编号。特别地,
代表该物品为主件,否则表示该附件从属于主件
。编号即输入顺序,从
开始。
特别地,保证全部物品的价格
均为
的倍数;且每个主件的附件数不超过
个。
在一行上输出一个整数,代表王强可获得的最大满意度。
50 5 20 3 5 20 3 5 10 3 0 10 2 0 10 1 0
130
在这个样例中,第三、四、五件物品为主件,第一、二件物品为第五件物品的附件。这就意味着,如果购买了第一件物品或第二件物品,则必须购买第五件物品;但是特别地,如果同时购买了第一件物品和第二件物品,则只需要购买一次第五件物品。
我们可以证明,购买一、二、五件商品,获得的满意度最大,为
。
1000 5 800 2 0 400 5 1 300 5 1 400 3 0 500 2 0
2200
本题已于下方时间节点更新,请注意题解时效性:
1. 2025-05-15 更新题面,新增几组hack数据(暂未进行重测)。
2. 2024-12-13 更新题面。
使用纯搜索的方法,求解空间是n个物品中选择购买m个物品(m<n)的排列组合,但是因为这样求解空间过大,一一列举时间不够,所以我采用了蒙特卡洛算法,每次循环列举n个例子,直到达到停止条件,不过很难在1s内收敛到最优解。
#include
#include
#include // 包含时间库用于种子初始化
struct object
{
int price;
int importance;
int kind;
};
int main() {
int money, num;
int satisfaction_max;
scanf("%d %d",&money, &num);
struct object *items= (struct object *)malloc(num*3*sizeof(int));
//储存数据
for(int i=0;i<num;i++)
{
scanf("%d %d %d",&items[i].price,&items[i].importance,&items[i].kind);
}
//初始化随机数种子
srand(time(NULL));
//创建求解空间,求解空间为n*n,为1则买这个物品,为0则不
char ** solveplace=(char **) malloc(num*sizeof(char*));// 动态分配一个 n x n 的二维数组
int satisfaction_max_stableCount = 0;//蒙特卡洛算法停止条件
int satisfaction_max_before=0;
for(int i=0;i<num;i++)
{
solveplace[i]=(char*)malloc(num*sizeof(char));
}
SOLVE:
//使用随机数创建求解例子
for(int i=0;i<num;i++)
{
for(int j=0;j<num;j++)
{
double rand_num = (double)rand() / RAND_MAX; // 生成一个 0 到 1 之间的随机数
if(rand_num<0.5)
solveplace[i][j]=0;
else
solveplace[i][j]=1;
}
}
//将不符合附件规定的删除
for(int i=0;i<num;i++)
{
for(int j=0;j<num;j++)
{
if(solveplace[i][j]&&items[j].kind)//如果它是附件
{
if(solveplace[i][items[j].kind-1]==0)//如果这个附件的主件没有选择
solveplace[i][0]=-1;//剔除这个求解,用-1作为标志
}
}
}
//计算所用的钱,将大于所用钱的的删除
for(int i=0;i<num;i++)
{
if(solveplace[i][0]==-1)
continue;
int money_=0;
for(int j=0;j<num;j++)
{
if(solveplace[i][j])
money_+=items[j].price;
}
if(money_>money)//价格超了,删除这个求解
solveplace[i][0]=-1;
}
//寻找剩余可行解中重要值最大的
for(int i=0;i<num;i++)
{
if(solveplace[i][0]==-1)
continue;
int satisfaction=0;
for(int j=0;j<num;j++)
{
if(solveplace[i][j])
satisfaction+=items[j].price*items[j].importance;
}
if(satisfaction>satisfaction_max)
satisfaction_max = satisfaction;
}
if(satisfaction_max==satisfaction_max_before)
satisfaction_max_stableCount++;
satisfaction_max_before = satisfaction_max;
//蒙特卡洛算法停止判断
if(satisfaction_max_stableCount<70000)
{
goto SOLVE;
}
else
printf("%d",satisfaction_max);
return 0;
}
#include <stdio.h>
#include <malloc.h>
#include <math.h>
struct goodssub{
int price;
int worth;
struct goodssub * nxt;
};
struct goodsmain{
int index;
int price;
int worth;
int sub_num;
int a[32000];
struct goodssub* mysub;
};
struct goodsmain goods[60];
int howmanyzero(int n){
int ret = 0;
while (n % 10 == 0){
ret ++;
n/=10;
}
return ret;
}
int main() {
int price, totnum, mainnum=0;
scanf("%d %d", &price, &totnum);
int tmp[60][3];
int tmpnum=0;
int minzero = 100;
for (int i=0; i < totnum; i++){
int v, p, q;
scanf("%d %d %d", &v, &p, &q);
if (minzero > howmanyzero(v)) minzero = howmanyzero(v);
if (q == 0){
goods[mainnum].index = i + 1;
goods[mainnum].price = v;
goods[mainnum].worth = p;
goods[mainnum].sub_num = 0;
goods[mainnum].mysub = NULL;
mainnum ++;
}else {
tmp[tmpnum][0] = v;
tmp[tmpnum][1] = p;
tmp[tmpnum][2] = q;
tmpnum ++ ;
}
}
int myzero = pow(10, minzero);
for (int i=0; i < mainnum; i++) goods[i].price /= myzero;
price /= myzero;
for (int i=0; i < tmpnum; i++) tmp[i][0] /= myzero;
for (int i=0; i < tmpnum; i++){
int thisindex = 0;
int j;
for(j=0; j < mainnum; j++) if (goods[j].index == tmp[i][2]) break;
struct goodsmain *gp = &goods[j];
struct goodssub *gs ;
if (gp->sub_num == 0){
gp->mysub = malloc(sizeof(struct goodssub));
gs = gp->mysub;
}else {
gs = gp->mysub;
for (int ii=0; ii < gp->sub_num - 1; ii++) gs = gs->nxt;
gs -> nxt = malloc(sizeof(struct goodssub));
gs = gs->nxt;
}
gs->price = tmp[i][0];
gs->worth = tmp[i][1];
gs->nxt = NULL;
gp->sub_num ++;
}
int * aaa = malloc(sizeof(int) * (price + 1) * (mainnum + 1));
for (int i=0; i <= price; i++) aaa[i] = 0;
for (int i=0; i < mainnum; i++){
if (goods[i].sub_num == 0){
for (int ii=0; ii <= price; ii++) goods[i].a[ii] = (ii >= goods[i].price)?goods[i].price * goods[i].worth:0;
}else{
int *aa = malloc(sizeof(int) * (price + 1) * (goods[i].sub_num + 1));
for (int ii=goods[i].price; ii <= price; ii++) aa[ii] = goods[i].price * goods[i].worth;
struct goodssub *gs = goods[i].mysub;
for (int jj = 1; jj <= goods[i].sub_num; jj++){
for (int ii=goods[i].price; ii <= price; ii++){
int max = aa[(jj-1) * (price + 1) + ii];
if (ii - gs->price >= goods[i].price)
if (aa[(jj-1) * (price + 1) + ii - gs->price] + gs->price * gs->worth > max)
max = aa[(jj-1) * (price + 1) + ii - gs->price] + gs->price * gs->worth;
aa[jj * (price + 1) + ii ] = max;
}
gs = gs->nxt;
}
for (int ii=0; ii <= price; ii++) goods[i].a[ii] = (ii < goods[i].price)?0:aa[goods[i].sub_num * (price + 1) + ii];
free(aa);
}
for (int j=0; j<=price; j++){
int max = 0;
for (int k=0; k <= j; k++)
if (aaa[(i) * (price + 1) + k] + goods[i].a[j-k] > max) max = aaa[(i) * (price + 1) + k] + goods[i].a[j-k];
aaa[(i+1)*(price+1)+j] = max;
}
}
printf("%d", aaa[mainnum * (price + 1) + price] * myzero);
return 0;
} #include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define max(a,b) a>=b?a:b
int main()
{
int N,m,v,p,q,num=0,k=0;
scanf("%d %d",&N,&m);
int money[4][m];
int position[3][m];
//初始化
for(int i=0;i<4;i++)
for(int j=0;j<m;j++)
money[i][j]=0;
//赋值
for(int i=0;i<m;i++)
{
scanf("%d %d %d",&v,&p,&q);
if(q!=0)
{
int j = money[3][q-1]+1;
money[j][q-1]=v;
position[j][q-1]=p;
money[3][q-1] +=1;
continue;
}
money[0][i]=v;
position[0][i]=p;
num++;
}
int value[4][num];
int weight[4][num];
//处理数据
for(int i=0;i<m;i++)
{
if(money[0][i]==0)
continue;
//value
value[0][k]=money[0][i];
value[1][k]=money[0][i]+money[1][i];
value[2][k]=money[0][i]+money[2][i];
value[3][k]=money[0][i]+money[1][i]+money[2][i];
//weight
weight[0][k]=money[0][i]*position[0][i];
weight[1][k]=money[0][i]*position[0][i]+money[1][i]*position[1][i];
weight[2][k]=money[0][i]*position[0][i]+money[2][i]*position[2][i];
weight[3][k]=money[0][i]*position[0][i]+money[2][i]*position[2][i]+money[1][i]*position[1][i];
k++;
}
int ** DP = malloc((N/10+1)*sizeof(int *));
int max_above = 0;
for(int i=0;i<(N/10+1);i++)
{
DP[i] = malloc(num*sizeof(int));
for(int j =0;j<num;j++)
{
int max_w=0;
//***附件
for(int k=0;k<4;k++)
{
int max_p= 0;
//钱够不够,不够就滚
if((i*10)<value[k][j])
continue;
for(int temp_j=0;temp_j<j;temp_j++)
max_p = max(max_p,DP[(i*10-value[k][j])/10][temp_j]);
max_w = max(max_w,max_p+weight[k][j]);
}
DP[i][j] = max_w;
max_above = max(max_above,max_w);
}
}
printf("%d",max_above);
return 0;
} 记录一下自己的思路 #include <stdio.h>
static int level[61][3201];
static int v[60], p[60], q[60];
int lastbig = 0;
int max(int a, int b)
{
if (a>=b) {
lastbig = 0;
return a;
} else {
lastbig = 1;
return b;
}
}
int main() {
int N, m;
scanf("%d %d", &N, &m);
N /= 10;
for (int j = 0; j < m; j++) {
scanf("%d %d %d", &v[j], &p[j], &q[j]);
v[j] /= 10;
}
for (int j = 0; j < m; j++) {
int cq = q[j];
if (cq) {
cq -= 1;
for (int i = N - v[j]; i >= 0; i--) {
if (level[j][i]) continue;
if (level[cq][i]) {
level[60][i+v[j]] = max(level[60][i+v[j]], level[60][i] + v[j]*p[j]);
if (lastbig) {
for (int k = 0; k < m; k++)
level[k][i+v[j]] = level[k][i];
level[j][i+v[j]] = 1;
}
}
else if (i <= N-v[j]-v[cq]){
level[60][i+v[j]+v[cq]] = max(level[60][i+v[j]+v[cq]], level[60][i] + v[j]*p[j] + v[cq]*p[cq]);
if (lastbig) {
for (int k = 0; k < m; k++)
level[k][i+v[j]+v[cq]] = level[k][i];
level[j][i+v[j]+v[cq]] = 1;
level[cq][i+v[j]+v[cq]] = 1;
}
}
}
} else {
for (int i = N - v[j]; i >= 0; i--) {
if (level[j][i]) continue;
level[60][i+v[j]] = max(level[60][i+v[j]], level[60][i] + v[j]*p[j]);
if (lastbig) {
for (int k = 0; k < m; k++)
level[k][i+v[j]] = level[k][i];
level[j][i+v[j]] = 1;
}
}
}
}
printf("%d", level[60][N] * 10);
return 0;
} #include <stdio.h>
typedef struct goods{
int prices; //物品的价格
int value; //满意度
}GOODS ;
int max(int a, int b)
{
return a>b ? a:b;
}
int main() {
int N,m,a,b,c;
GOODS goods[60][3] = {0}; //goods[i][0]代表主件、goods[i][1]代表附件1、goods[i][2]代表附件2
scanf("%d %d", &N, &m);
for(int i=1; i<=m; i++)
{
scanf("%d %d %d", &a, &b, &c);
a /= 10; b *= a;
if (c == 0)
{
goods[i][0].prices = a; goods[i][0].value = b;
}
else
{
if (goods[c][1].prices == 0)
{
goods[c][1].prices = a; goods[c][1].value = b;
}
else
{
goods[c][2].prices = a; goods[c][2].value = b;
}
}
}
N /= 10; //每件物品的价格(都是 10 元的整数倍)
int dp[60][3200] = {0};
for(int i=1; i<=m; i++)
{
for(int j=1; j<=N; j++)
{
int a = goods[i][0].prices, b = goods[i][0].value;
int c = goods[i][1].prices, d = goods[i][1].value;
int e = goods[i][2].prices, f = goods[i][2].value;
dp[i][j] = j >= a ? max(dp[i-1][j-a] + b, dp[i-1][j]) : dp[i-1][j];
dp[i][j] = j >= (a+c) ? max(dp[i-1][j-a-c] + b + d, dp[i][j]) : dp[i][j];
dp[i][j] = j >= (a+e) ? max(dp[i-1][j-a-e] + b + f, dp[i][j]) : dp[i][j];
dp[i][j] = j >= (a+c+e) ? max(dp[i-1][j-a-c-e] + b + d + f, dp[i][j]) : dp[i][j];
}
}
printf("%d", dp[m][N]*10);
return 0;
}
//四种情况:1、主件;2、主件+附件1;3、主件+附件2;4、主件+附件1+附件2
//dp[i][j] = max(物品不放入背包,主件,主件+附件1,主件+附件2,主件+附件1+附件2)
/*
int a = prices[i][0], b = value[i][0];
int c = prices[i][1], d = value[i][1];
int e = prices[i][2], f = value[i][2];
dp[i][j] = j >= a ? max(dp[i-1][j-a] + b, dp[i-1][j]) : dp[i-1][j];
dp[i][j] = j >= (a+c) ? max(dp[i-1][j-a-c] + b + d, dp[i][j]) : dp[i][j];
dp[i][j] = j >= (a+e) ? max(dp[i-1][j-a-e] + b + f, dp[i][j]) : dp[i][j];
dp[i][j] = j >= (a+c+e) ? max(dp[i-1][j-a-c-e] + b + d + f, dp[i][j]) : dp[i][j];
*/ #include<stdio.h>
typedef struct Things {
int index;
int price;
int importance;
int pIndex;
int fujian[2];
int fujianIndex;
};
int getZhuId(struct Things one) {
if (one.pIndex > 0) {
return one.pIndex;
}
return one.index;
}
int comp(struct Things first, struct Things second) {
if (getZhuId(first) < getZhuId(second)) {
return -1;
}
if (getZhuId(first) > getZhuId(second)) {
return 1;
}
// zhuid equal
if (first.pIndex == 0) {
return -1;
}
if (second.pIndex == 0) {
return 1;
}
// all is fujian ,then sort with index
return first.index - second.index;
}
int max(int a, int b) {
if (a > b) {
return a;
}
return b;
}
int getPricePlusImport(struct Things tg) {
return tg.price * tg.importance;
}
int main(){
int allMoney = 0;
int count = 0;
struct Things thingArray[60];
while (scanf("%d %d", &allMoney, &count) != EOF) {
for (int i = 1; i < count + 1; i++) {
struct Things tg;
tg.index = i;
tg.fujianIndex = -1;
scanf("%d %d %d", &tg.price, &tg.importance, &tg.pIndex);
thingArray[i - 1] = tg;
}
// resort zhujian sort with fujian
for (int i = 0; i < count; i++) {
// struct Things curr = thingArray[i];
int minIndex = i;
for (int j = i + 1; j < count; j++) {
struct Things curr = thingArray[j];
struct Things min = thingArray[minIndex];
if (comp(curr, min) < 0) {
minIndex = j;
}
}
// swap minIndex with i point
struct Things temp = thingArray[i];
thingArray[i] = thingArray[minIndex];
thingArray[minIndex] = temp;
}
int col = (allMoney / 10) + 1;
int dp[count][col];
for (int i = 0; i < count; i++) {
for (int j = 0; j < col; j++) {
if (j == 0) {
dp[i][j] = 0;
continue;
}
// loop judge
int money = j * 10;
if (i == 0) {
int value = 0;
if (money < thingArray[i].price) {
dp[i][j] = 0;
continue;
// return 0;
}
dp[i][j] = getPricePlusImport(thingArray[i]);
continue;
// return getPricePlusImport(thingArray[i]);
}
//not use i;
int notUseI = dp[i - 1][j];
// use i;
int useI;
// things on i is zhujian
if (thingArray[i].pIndex == 0) {
// can't use i
if (money < thingArray[i].price) {
dp[i][j] = notUseI;
continue;
// return 0;
// return notUseI;
}
// can use i
useI = dp[i - 1][ (money - thingArray[i].price) / 10] + getPricePlusImport(thingArray[i]);
dp[i][j] = max(notUseI, useI);
continue;
// return max(notUseI, useI);
// return 0;
}
// things on i is fujian
int fujianIndex = (thingArray[i - 1].pIndex == 0) ? 2 : 3;
// with first fujian
if (fujianIndex == 2) {
int needMoney = thingArray[i - 1].price + thingArray[i].price;
// can't use i
if (money < needMoney) {
dp[i][j] = notUseI;
continue;
// return notUseI;
// return 0;
}
// can use i, fujian must use with zhujian ,so i must -2
if (i < 2) {
useI = getPricePlusImport(thingArray[i]) + getPricePlusImport(thingArray[i - 1]);
} else {
useI = dp[i - 2][ (money - needMoney) / 10] + getPricePlusImport(thingArray[i]) +
getPricePlusImport(thingArray[i - 1]);
}
dp[i][j] = max(notUseI, useI);
continue;
// return max(notUseI, useI);
// return 0;
}
// with secord fujian
if (fujianIndex == 3) {
int singleUse1 = 0;
int doubleUse = 0;
// single fujian with zhujian
int needMoney = thingArray[i - 2].price + thingArray[i].price;
// single fujian with zhujian can't use i, then don't consider double use
if (money < needMoney) {
dp[i][j] = notUseI;
continue;
// return notUseI;
// return 0;
}
// can use i, fujian must use with zhujian ,so i must -2
if (i <= 2) {
singleUse1 = getPricePlusImport(thingArray[i]) + getPricePlusImport(thingArray[i - 2]);
} else {
singleUse1 = dp[i - 3][ (money - needMoney) / 10] + getPricePlusImport(thingArray[i]) +
getPricePlusImport(thingArray[i - 2]);
}
// double use fujian
needMoney = thingArray[i - 2].price + thingArray[i].price + thingArray[i - 1].price;
// can't double use, then return
if (money < needMoney) {
dp[i][j] = max(notUseI, singleUse1);
continue;
// return max(notUseI, singleUse1);
// return 0;
}
if (i <= 2) {
doubleUse = getPricePlusImport(thingArray[i]) + getPricePlusImport(thingArray[i - 2]) +
getPricePlusImport(thingArray[i - 1]);
} else {
doubleUse = dp[i - 3][ (money - needMoney) / 10] + getPricePlusImport(thingArray[i]) +
getPricePlusImport(thingArray[i - 2]) + getPricePlusImport(thingArray[i - 1]);
}
singleUse1 = max(notUseI, singleUse1);
dp[i][j] = max(singleUse1, doubleUse);
continue;
// return max(singleUse1, doubleUse);
// return 0;
}
// loop judge end
printf("invalid code execute, %d, %d", i, j);
}
}
printf("%d", dp[count -1][col - 1]);
}
} #include <stdio.h>
#define N 60
#define M 32000
int price[N][3],value[N][3],f[N][M]; //二维数组的第一列代表主件的属性,第2和3列分别表示附件1和2的属性
int max(int a,int b) //其中price二维数组存储价格,value二维数组存储价值(价格*重要度)
{ //f二维数组的值,表示在n个主件(包含附件)可购买,且预算为m情况下的最大价值之和
return (a>b?a:b);
}
int main()
{
int m,n,i,p1,w,z,j,p[N][3],v[N][3],temp[5]; //二维数组p和v与上述描述的二维数组作用相似,不过此时是从第1行依行逐次存放物品属性
scanf("%d%d",&m,&n); //输入钱m和可购买的物件n
for(i=1;i<=n;i++)
{
scanf("%d%d%d",&p1,&w,&z); //输入每一件物品的价格p,重要度w,是否主件标志z
if(z==0)
{
price[i][0]=p1; //若z==0,表示为主件,属性存放在第i行的第0列
value[i][0]=p1*w;
}
else
{
if(price[z][1]==0) //若有第一个出现的附件,其属性存放在第z行的第1列
{
price[z][1]=p1;
value[z][1]=p1*w;
}
else
{
price[z][2]=p1; //若有第二个出现的附件,其属性存放在第z行的第2列
value[z][2]=p1*w;
}
}
}
for(i=1,j=1;i<=n;i++) //将以上二维数组的值,按顺序转移到新的二维数组中,这样就不会有很多附件的0的数据穿插其中
{
if(price[i][0]!=0)
{
p[j][0]=price[i][0];p[j][1]=price[i][1];p[j][2]=price[i][2];
v[j][0]=value[i][0];v[j][1]=value[i][1];v[j][2]=value[i][2];
j++;
}
}
n=j-1; //n表示主件个数
for(i=1;i<=n;i++)
{
for(j=1;j<=m;j++)
{
for(w=0;w<5;w++)
{
temp[w]=0; //temp数组存放价值
}
temp[0]=f[i-1][j]; //temp[0]表示不买第i个主件所能够得到的最大价值之和
if(j>=p[i][0])
{
temp[1]=f[i-1][j-p[i][0]]+v[i][0]; //temp[1]表示买第i个主件(仅主件)后所能够得到的最大价值之和
}
if(j>=(p[i][0]+p[i][1]))
{
temp[2]=f[i-1][j-p[i][0]-p[i][1]]+v[i][0]+v[i][1]; //temp[2]表示买第i个主件+附件1后所能够得到的最大价值之和
}
if(j>=(p[i][0]+p[i][2]))
{ //下同
temp[3]=f[i-1][j-p[i][0]-p[i][2]]+v[i][0]+v[i][2];
}
if(j>=(p[i][0]+p[i][1]+p[i][2]))
{
temp[4]=f[i-1][j-p[i][0]-p[i][1]-p[i][2]]+v[i][0]+v[i][1]+v[i][2];
}
f[i][j]=max(temp[4],max(max(temp[0],temp[1]),max(temp[2],temp[3]))); //取数组temp内最大值,存放于f[i][j]
}
}
printf("%d\n",f[n][m]); //打印f[n][m],即在n个主件(包含附件)可购买,且预算为m情况下的最大价值之和
return 0;
}
//写了很久,终于写出来了,dp是真难啊 #include <stdio.h>
#include <string.h>
int max(int a, int b){
return a>b?a:b;
}
int main(){
int N, m, i, j;
while(scanf("%d %d", &N, &m) != EOF){
int v[m+1], p[m+1], q[m+1];
int dp[m+1][N+1];//i个物品,有j钱
int appendix[m+1][3];
int count = 0;
memset(dp, 0, sizeof(dp));
memset(appendix, 0, sizeof(appendix));//附件数=0
v[0] = p[0] = 0;
for(i=1; i<=m; i++){
scanf("%d %d %d", &v[i], &p[i], &q[i]); //v=价格,p=重要 ,q主附件
}
j = 1;
q[0] = -1;
for(i=1; i<=m; i++){
if(q[i]>0){
appendix[q[i]][j++] = i;//记录主剑的附件号码
}
}
for(i=1; i<=m; i++){
if(q[i] > 0){
count++;
}
for(j=10; j<=N; j+=10){
if(q[i] == 0){
if(j - v[i] >= 0){
dp[i][j] = max(dp[i-1-count][j-v[i]] + v[i]*p[i], dp[i-1-count][j]);
if(j-v[i]-v[appendix[i][1]] >= 0 && appendix[i][1] > 0){
dp[i][j] = max(dp[i-1-count][j-v[i]-v[appendix[i][1]]] + v[i]*p[i]+ v[appendix[i][1]]*p[appendix[i][1]], dp[i][j]);
}
if(j-v[i]-v[appendix[i][2]] >= 0 && appendix[i][2] > 0){
dp[i][j] = max(dp[i-1-count][j-v[i]-v[appendix[i][2]]] + v[i]*p[i]+ v[appendix[i][2]]*p[appendix[i][2]], dp[i][j]);
}
if(j-v[i]-v[appendix[i][1]]-v[appendix[i][2]] >= 0 && appendix[i][2] > 0 && appendix[i][1] > 0){
dp[i][j] = max(dp[i-1-count][j-v[i]-v[appendix[i][1]]-v[appendix[i][2]]] + v[i]*p[i]+ v[appendix[i][1]]*p[appendix[i][1]] + v[appendix[i][2]]*p[appendix[i][2]], dp[i][j]);
}
}else{
dp[i][j] = dp[i-1-count][j];
}
}
}
if(q[i] == 0){
count = 0;
}
}
printf("%d", dp[m][N]);
}
return 0;
} #include <stdio.h>
int max(int a,int b){
return a>b?a:b;
}
int main(void){
//背包问题延展,有附件,最多两个,要考虑到附件
int N,m;
while (scanf("%d %d",&N,&m)!=EOF) {
int value[63][3]={0};
int weight[63][3]={0};
int q=0,p=0,v=0;
for(int i=1;i <= m;i++)
{
scanf("%d %d %d",&v,&p,&q);
if(q){//附件
if(!value[q][1]){//第一个附件
value[q][1] = v;//价格
weight[q][1] = v*p;//重要度
}else{//第二个附件
value[q][2] = v;
weight[q][2] = ***bsp; }
}else{//主件
value[i][0] = v;
weight[i][0] = ***bsp; }
}
int n=N/10,value_total = 0,weight_total = 0;
int total_max[3200] = {0};
for(int i=1;i <= m;i++)
{
for(int j=n;j >= value[i][0]/10;j--)
{
total_max[j] = max(total_max[j],total_max[j - value[i][0]/10] + weight[i][0]);
value_total = value[i][1]/10 + value[i][0]/10;
weight_total = weight[i][1] + weight[i][0];
if(value[i][1] && j >= value_total)
{
total_max[j] = max(total_max[j],total_max[j - value_total] + weight_total);
}
value_total += value[i][2]/10;
weight_total += weight[i][2];
if(value[i][2] && j >= value_total)
{
total_max[j] = max(total_max[j],total_max[j - value_total] + weight_total);
}
}
}
printf("%d\n",total_max[n]);
}
return 0;
}