TYVJ 1057 金明的预算方案 解题报告
这题好像是某届NOIP的原题,我用的简单DP,因为主件最多两个子件,所以没什么考虑的,多判断几次,但是这代码太猥琐了,写的我一头的汗。不过还好,一次AC!
================================华丽的分割线 ================================
#include <stdio.h> #include <stdlib.h> struct thing{ int p, i; int len; int sub[2]; }thing[60]; int end; int f[32001]; int main(int argc, char **argv) { int i, j; int n, m; int a, b, c; scanf("%d%d", &m, &n); for(i = 0; i < n; i++){ scanf("%d%d%d", &a, &b, &c); thing[end].p = a; thing[end].i = b; if(c != 0){ thing[c - 1].sub[thing[c - 1].len++] = i; //说明它不是主件 thing[end].len = -1; } end++; } for(i = 0; i < n; i++){ if(thing[i].len == -1){ continue; } for(j = m; j >= thing[i].p; j--){ if(f[j] < f[j - thing[i].p] + (thing[i].p * thing[i].i)){ f[j] = f[j - thing[i].p] + (thing[i].p * thing[i].i); } if(thing[i].len >= 1){ if(j - thing[i].p - thing[thing[i].sub[0]].p >= 0 && f[j] < f[j - thing[i].p - thing[thing[i].sub[0]].p] + (thing[i].p * thing[i].i + thing[thing[i].sub[0]].p * thing[thing[i].sub[0]].i)){ f[j] = f[j - thing[i].p - thing[thing[i].sub[0]].p] + (thing[i].p * thing[i].i + thing[thing[i].sub[0]].p * thing[thing[i].sub[0]].i); } if(thing[i].len == 2){ if(j - thing[i].p - thing[thing[i].sub[1]].p >= 0 && f[j] < f[j - thing[i].p - thing[thing[i].sub[1]].p] + (thing[i].p * thing[i].i + thing[thing[i].sub[1]].p * thing[thing[i].sub[1]].i)){ f[j] = f[j - thing[i].p - thing[thing[i].sub[1]].p] + (thing[i].p * thing[i].i + thing[thing[i].sub[1]].p * thing[thing[i].sub[1]].i); } if(j - thing[i].p - thing[thing[i].sub[0]].p - thing[thing[i].sub[1]].p >= 0 && f[j] < f[j - thing[i].p - thing[thing[i].sub[0]].p - thing[thing[i].sub[1]].p] + (thing[i].p * thing[i].i + thing[thing[i].sub[1]].p * thing[thing[i].sub[1]].i + thing[thing[i].sub[0]].p * thing[thing[i].sub[0]].i)){ f[j] = f[j - thing[i].p - thing[thing[i].sub[0]].p - thing[thing[i].sub[1]].p] + (thing[i].p * thing[i].i + thing[thing[i].sub[1]].p * thing[thing[i].sub[1]].i + thing[thing[i].sub[0]].p * thing[thing[i].sub[0]].i); } } } } } printf("%d\n", f[m]); return 0; }