http://www.vijos.cn/Problem_Show.asp?id=1313
#include<iostream>
using namespace std;
struct Node
{
    
int v;//该物品的价格
    int p;//该物品的重要度
    int mark;//标记该物品是否为主件,mark=0表示为主件,否则表示其主件号
    int fj1;//附件1 * fj1 = 0 表示没有附件1,否则为附件号
    int fj2;//附件2 * fj2 = 0 表示没有附件2,否则为附件号
}

int MAX(int x,int y)
{
    
if(x>y)
        
return x;
    
else
        
return y;
}

int main()
{
    
int N,m;//N 钱数,m 物品数量
    while(cin>>N>>m)
    
{
        
int i,j,temp,p1,p2;
        
int dp[32001];
        Node obj[
60];
        
for(i=1;i<=m;i++//开始都没有附件
            obj[i].fj1 = obj[i].fj2 = 0;

        
for(i=1;i<=m;i++)
        
{            
            scanf(
"%d%d%d",&obj[i].v,&obj[i].p,&obj[i].mark);            
            
if(obj[i].mark != 0//不是主件 就要找其主件
            {
                
if(obj[obj[i].mark].fj1 != 0)
                
{
                    
if(obj[obj[obj[i].mark].fj1].v > obj[i].v)//保证附件1的价格要小
                    {
                        temp 
= obj[obj[i].mark].fj1;
                        obj[obj[i].mark].fj1 
= i;
                        obj[obj[i].mark].fj2 
= temp;
                    }

                    
else 
                        obj[obj[i].mark].fj2 
= i;
                }

                
else 
                    obj[obj[i].mark].fj1 
= i;
            }

        }

        
if(obj[1].mark == 0)
        
{
            
if(obj[1].fj1 == 0 && obj[1].fj2 == 0)
            
{
                
for(j=0;j<obj[1].v;j++)
                    dp[j] 
= 0;
                
for(;j<=N;j++)
                    dp[j] 
= obj[1].v * obj[1].p;
            }

            
else if(obj[1].fj1 != 0 && obj[1].fj2 == 0)
            
{
                p1 
= obj[1].fj1;
                
for(j=0;j<obj[1].v;j++)//什么都不能买
                    dp[j] = 0;
                
for(;j<obj[1].v + obj[p1].v ;j++)//只能买主件
                    dp[j] = obj[1].v * obj[1].p;
                
for(;j<=N;j++)
                    dp[j] 
= obj[1].v * obj[1].p + obj[p1].v * obj[p1].p;
            }
 
            
else
            
{
                p1 
= obj[1].fj1;
                p2 
= obj[1].fj2;
                
for(j=0;j<obj[1].v;j++)//什么都不能买
                    dp[j] = 0;

                
for(;j<obj[1].v + obj[p1].v ;j++//只能买主件
                    dp[j] = obj[1].v*obj[1].p;

                
for(;j<obj[1].v + obj[p2].v ;j++//能买主件与附件1
                    dp[j] = obj[1].v*obj[1].p + obj[p1].v*obj[p1].p;

                
for(;j<obj[1].v + obj[p1].v + obj[p2].v ;j++//能买主件与一个附件
                    dp[j] = MAX(obj[1].v*obj[1].p + obj[p1].v*obj[p1].p,obj[1].v*obj[1].p + obj[p2].v*obj[p2].p);

                
for(;j<=N;j++//都能买
                    dp[j] = obj[1].v*obj[1].p + obj[p1].v*obj[p1].p + obj[p2].v*obj[p2].p;
            }

        }
//if(obj[1].mark == 0)
        else //第1件物品是附件
        {
            
for(j=0;j<=N;j++)
                dp[j] 
= 0;
        }

        
        
for(i=2;i<=m;i++)
        
{
            
if(obj[i].mark == 0)//第i件物品是主件
            {
                
if(obj[i].fj1 == 0 && obj[i].fj2 == 0//没有附件
                {
                    
//只够买主件
                    for(j=N;j>=obj[i].v;j--)
                        dp[j] 
= MAX(dp[j],dp[j-obj[i].v] + obj[i].v*obj[i].p);
                }

                
else if(obj[i].fj1 != 0 && obj[i].fj2 == 0//有附件1
                {
                    p1 
= obj[i].fj1;
                    
for(j=N;j>=obj[i].v + obj[p1].v;j--)
                    
{
                        temp 
= dp[j];
                        
//买主件与附件1
                        if(temp < dp[j-obj[i].v-obj[p1].v] + obj[i].v*obj[i].p + obj[p1].v*obj[p1].p)
                            temp 
= dp[j-obj[i].v-obj[p1].v] + obj[i].v*obj[i].p + obj[p1].v*obj[p1].p;
                        
//只买主件
                        if(temp < dp[j-obj[i].v ] + obj[i].v*obj[i].p)
                            temp 
= dp[j-obj[i].v ] + obj[i].v*obj[i].p;
                        dp[j] 
=temp;
                    }

                    
//只够买主件
                    for(;j>=obj[i].v;j--)
                        dp[j] 
= MAX(dp[j],dp[j-obj[i].v] + obj[i].v*obj[i].p);
                }

                
else //有两个附件
                {
                    p1 
= obj[i].fj1;
                    p2 
= obj[i].fj2;

                     
for(j=N;j>=obj[i].v + obj[p1].v + obj[p2].v;j--)
                    
{
                        temp 
= dp[j];
                        
//主件与两附件都买
                        if(temp < dp[j-obj[i].v-obj[p1].v-obj[p2].v] + obj[i].v*obj[i].p + obj[p1].v*obj[p1].p + obj[p2].v*obj[p2].p)
                            temp 
= dp[j-obj[i].v-obj[p1].v-obj[p2].v] + obj[i].v*obj[i].p + obj[p1].v*obj[p1].p + obj[p2].v*obj[p2].p;
                        
//买主件与附件2
                        if(temp < dp[j-obj[i].v-obj[p2].v] + obj[i].v*obj[i].p + obj[p2].v*obj[p2].p)
                            temp 
= dp[j-obj[i].v-obj[p2].v] + obj[i].v*obj[i].p + obj[p2].v*obj[p2].p;
                        
//买主件与附件1
                        if(temp < dp[j-obj[i].v-obj[p1].v] + obj[i].v*obj[i].p + obj[p1].v*obj[p1].p)
                            temp 
= dp[j-obj[i].v-obj[p1].v] + obj[i].v*obj[i].p + obj[p1].v*obj[p1].p;
                        
//只买主件
                        if(temp < dp[j-obj[i].v ] + obj[i].v*obj[i].p)
                            temp 
= dp[j-obj[i].v ] + obj[i].v*obj[i].p;
                        dp[j] 
= temp;
                    }

                    
for(;j>=obj[i].v + obj[p2].v;j--)
                    
{
                        temp 
= dp[j];
                        
//买主件与附件2
                        if(temp < dp[j-obj[i].v-obj[p2].v] + obj[i].v*obj[i].p + obj[p2].v*obj[p2].p)
                            temp 
= dp[j-obj[i].v-obj[p2].v] + obj[i].v*obj[i].p + obj[p2].v*obj[p2].p;
                        
//买主件与附件1
                        if(temp < dp[j-obj[i].v-obj[p1].v] + obj[i].v*obj[i].p + obj[p1].v*obj[p1].p)
                            temp 
= dp[j-obj[i].v-obj[p1].v] + obj[i].v*obj[i].p + obj[p1].v*obj[p1].p;
                        
//只买主件
                        if(temp < dp[j-obj[i].v ] + obj[i].v*obj[i].p)
                            temp 
= dp[j-obj[i].v ] + obj[i].v*obj[i].p;
                        dp[j] 
= temp;
                    }

                    
for(;j>=obj[i].v + obj[p1].v;j--)
                    
{
                        temp 
= dp[j];
                        
//买主件与附件1
                        if(temp < dp[j-obj[i].v-obj[p1].v] + obj[i].v*obj[i].p + obj[p1].v*obj[p1].p)
                            temp 
= dp[j-obj[i].v-obj[p1].v] + obj[i].v*obj[i].p + obj[p1].v*obj[p1].p;
                        
//只买主件
                        if(temp < dp[j-obj[i].v ] + obj[i].v*obj[i].p)
                            temp 
= dp[j-obj[i].v ] + obj[i].v*obj[i].p;
                        dp[j] 
= temp;
                    }

                    
//只够买主件
                    for(;j>=obj[i].v;j--)
                        dp[j] 
= MAX(dp[j],dp[j-obj[i].v] + obj[i].v*obj[i].p);            
                }

            }

        }

        cout
<<dp[N]<<endl;
    }

    
return 0;
}


/*
4500 12 
100 3 0 
400 5 0 
300 5 0
1400 2 0 
500 2 0 
800 2 4
1400 5 4 
300 5 0
1400 3 8 
500 2 0
1800 4 0
440 5 10
1000   5   
300   5   0   
400   2   0   
300   5   2   
300   4   2   
600   4   0
*/