相当于在背包上面挂vector,这样我们就可以求出容量为j所有k优解
转移是把dp[i-1][j][k] 和 dp[i-1][j-w[i]][k]向dp[i][j][k]上转移,因为这两个地方的k优解的2k个解里一定含有dp[i][j]的k优解,而且这两个序列有单调性
可以直接把所有数赋为-inf然后如果不满足从0开始装更新到最后也是负数,最后判断dp[n][m][k]是否是负数就可以了
然后滚动数组
1 /* 2 ID: ivorysi 3 LANG: C++ 4 TASK: theme 5 */ 6 #include <iostream> 7 #include <cstdio> 8 #include <cstring> 9 #include <algorithm> 10 #include <queue> 11 #include <set> 12 #include <vector> 13 #include <string.h> 14 #define siji(i,x,y) for(int i=(x);i<=(y);++i) 15 #define gongzi(j,x,y) for(int j=(x);j>=(y);--j) 16 #define xiaosiji(i,x,y) for(int i=(x);i<(y);++i) 17 #define sigongzi(j,x,y) for(int j=(x);j>(y);--j) 18 #define inf 0x7fffffff 19 #define ivorysi 20 #define mo 97797977 21 #define hash 974711 22 #define base 47 23 #define pss pair<string,string> 24 #define MAXN 5000 25 #define fi first 26 #define se second 27 #define pii pair<int,int> 28 typedef long long ll; 29 using namespace std; 30 int n,m,k; 31 int w[205],c[205]; 32 int dp[5005][55]; 33 int line[55],ans; 34 void solve() { 35 scanf("%d%d%d",&k,&m,&n); 36 siji(i,1,n) scanf("%d%d",&w[i],&c[i]); 37 siji(j,0,m) siji(i,1,k) dp[j][i]=-4000000; 38 dp[0][1]=0; 39 siji(i,1,n) { 40 gongzi(j,m,w[i]) { 41 int t1=1,t2=1; 42 siji(h,1,k) { 43 if(dp[j-w[i]][t1]+c[i] > dp[j][t2]) { 44 line[h]=dp[j-w[i]][t1]+c[i]; 45 ++t1; 46 } 47 else { 48 line[h]=dp[j][t2]; 49 ++t2; 50 } 51 } 52 siji(h,1,k) dp[j][h]=line[h]; 53 } 54 } 55 if(dp[m][k] < 0) {puts("no");return;} 56 siji(i,1,k) { 57 ans+=dp[m][i]; 58 } 59 printf("%d ",ans); 60 } 61 int main(int argc, char const *argv[]) 62 { 63 #ifdef ivorysi 64 freopen("24.in","r",stdin); 65 freopen("24.out","w",stdout); 66 #else 67 freopen("f1.in","r",stdin); 68 #endif 69 solve(); 70 return 0; 71 }