//n:0~i个物品;M:钱数 m[i-1]:第i个物品的价格v[i-1]:第i个物品的价值 //dp[n][M] //dp[i][j]你现在有j元,现有i个物品,每个物品价格m[i],价值v[i],你花钱买他们,可以获得的最大价值是多少? //初始化一个data //背包分组 #include <iostream> #include <vector> using namespace std; int main() { int N, m; cin >> N >> m; N /= 10; int price, priority, hasAttachment; //初始化一个data (m+1)X6 将附件的price和priority放入其从属的主件行,先初始化为0,0作废 vector<vector<int>> data(m + 1, vector<int>(6, 0)); for (int i = 1; i <= m; ++i) { //写成m+1了 cin >> price >> priority >> hasAttachment; //输入的为主件信息 if (hasAttachment == 0) { data[i][0] = price / 10; data[i][1] = priority; } //输入的是附件 else if (data[hasAttachment][2] == 0) { //未被占用 data[hasAttachment][2] = price / 10; data[hasAttachment][3] = priority; } else { data[hasAttachment][4] = price / 10; data[hasAttachment][5] = priority; } } //分组背包 vector<vector<int>> dp(m + 1, vector<int>(N + 1, 0)); //dp[][0]=0 for (int i = 1; i <= m; ++i) { for (int j = 1; j <= N; ++j) { int pricePrime = data[i][0]; int priceAttach1 = data[i][2]; int priceAttach2 = data[i][4]; int priorPrime = data[i][1]; int priorAttach1 = data[i][3]; int priorAttach2 = data[i][5]; //看剩下的钱够不够买 //只买主件0-1背包问题 dp[i][j] = (j - pricePrime) >= 0 ? max(dp[i - 1][j], dp[i - 1][j - pricePrime] + priorPrime * pricePrime) : dp[i - 1][j]; //以下3种情况是附件问题,通过与只买主件得到的dp[i][j](最大价值)作比较,结果存入dp[i][j] //买的主件+附件1 dp[i][j] = (j - pricePrime - priceAttach1) >= 0 ? max(dp[i][j], dp[i - 1][j - pricePrime - priceAttach1] + priorPrime * pricePrime + priorAttach1 * priceAttach1) : dp[i][j]; //买的主件+附件2 dp[i][j] = (j - pricePrime - priceAttach2) >= 0 ? max(dp[i][j], dp[i - 1][j - pricePrime - priceAttach2] + priorPrime * pricePrime + priorAttach2 * priceAttach2) : dp[i][j]; //买的主件带2个附件 dp[i][j] = (j - pricePrime - priceAttach1 - priceAttach2) >= 0 ? max(dp[i][j], dp[i - 1][j - pricePrime - priceAttach1 - priceAttach2] + priorPrime * pricePrime + priorAttach1 * priceAttach1 + priorAttach2 * priceAttach2) : dp[i][j]; } } cout << dp[m][N] * 10 << endl; } // 64 位输出请用 printf("%lld")