--Dirring love 音乐(01背包问题)

解题思路:

dp[i][j] 前 i 首歌放入 j 容量中的最大热情度。

前 i 首歌 放到 j 容量中 dp[i][j]= dp[i-1][j-m[i]]+r[i]   (注意:如果 j 容量 < m[i] 歌的大小 则不能放,即  dp[i][j]=dp[i-1][j] )

           不放              dp[i][j]=dp[i-1][j]

状态方程:

     dp[i][j]=max(dp[i-1][j],dp[i-1][j-m[i]]+r[i]);
 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 //int m[105],r[105],dp[105][10005];
 4 int main()
 5 {
 6     int n,v;
 7     while(scanf("%d%d",&n,&v)!=EOF)
 8     {
 9         int m[n+2],r[n+2],dp[n+2][v+4];
10         memset(dp,0,sizeof(dp));
11         memset(m,0,sizeof(m));
12         memset(r,0,sizeof(r));
13         for(int i=1; i<=n; i++)scanf("%d%d",&m[i],&r[i]);
14 
15         for(int i=1; i<=n; i++)
16             for(int j=v; j>=0; j--)
17             {
18                 dp[i][j]=dp[i-1][j];
19                 if(j>=m[i])
20                     dp[i][j]=max(dp[i-1][j],dp[i-1][j-m[i]]+r[i]);
21             }
22         printf("%d
",dp[n][v]);
23     }
24     return 0;
25 }

优化空间复杂度:(降维)
#include<bits/stdc++.h>
using namespace std;
int main(void)
{
    int n,v;
    while(scanf("%d%d",&n,&v)!=EOF)
    {
        int m[n+4],r[n+4],dp[v+5];
        memset(m,0,sizeof(m));
        memset(r,0,sizeof(r));
        for(int i=0; i<n; i++)scanf("%d%d",&m[i],&r[i]);
        memset(dp,0,sizeof(dp));
        for(int i=0; i<=n; ++i)
            for(int j=v; j>=m[i]; j--)
                dp[j]= max(dp[j],dp[j-m[i]]+r[i]);
        printf("%d
",dp[v]);
    }
    return 0;
}
原文地址:https://www.cnblogs.com/A--Q/p/5761570.html