zoukankan      html  css  js  c++  java
  • UVA 624 CD【01背包+路径记录】

    You have a long drive by car ahead. You have a tape recorder, but unfortunately your best music is on
    CDs. You need to have it on tapes so the problem to solve is: you have a tape N minutes long. How
    to choose tracks from CD to get most out of tape space and have as short unused space as possible.
    Assumptions:
    • number of tracks on the CD does not exceed 20
    • no track is longer than N minutes
    • tracks do not repeat
    • length of each track is expressed as an integer number
    • N is also integer
    Program should find the set of tracks which fills the tape best and print it in the same sequence as
    the tracks are stored on the CD
    Input
    Any number of lines. Each one contains value N, (after space) number of tracks and durations of the
    tracks. For example from first line in sample data: N = 5, number of tracks=3, first track lasts for 1
    minute, second one 3 minutes, next one 4 minutes
    Output
    Set of tracks (and durations) which are the correct solutions and string ‘sum:’ and sum of duration
    times.
    Sample Input
    5 3 1 3 4
    10 4 9 8 4 2
    20 4 10 5 7 4
    90 8 10 23 1 2 3 4 5 7
    45 8 4 10 44 43 12 9 8 2
    Sample Output
    1 4 sum:5
    8 2 sum:10
    10 5 4 sum:19
    10 23 1 2 3 4 5 7 sum:55
    4 10 12 9 8 2 sum:45

    【代码】:

    【一维 + vis标记数组 + 倒序输出】:用一个vis[i][j]记录容量为j的背包里面有没有用到过i物品,物品是倒着放的。

    #include<cstdio>
    #include<string>
    #include<cstdlib>
    #include<cmath>
    #include<iostream>
    #include<cstring>
    #include<set>
    #include<queue>
    #include<algorithm>
    #include<vector>
    #include<map>
    #include<cctype>
    #include<stack>
    #include<sstream>
    #include<list>
    #include<assert.h>
    #include<bitset>
    #include<numeric>
    #define debug() puts("++++")
    #define gcd(a,b) __gcd(a,b)
    #define lson l,m,rt<<1
    #define rson m+1,r,rt<<1|1
    #define fi first
    #define se second
    #define pb push_back
    #define sqr(x) ((x)*(x))
    #define ms(a,b) memset(a,b,sizeof(a))
    #define sz size()
    #define be begin()
    #define pu push_up
    #define pd push_down
    #define cl clear()
    #define lowbit(x) -x&x
    #define all 1,n,1
    #define rep(i,n,x) for(int i=(x); i<(n); i++)
    #define in freopen("in.in","r",stdin)
    #define out freopen("out.out","w",stdout)
    using namespace std;
    typedef long long LL;
    typedef unsigned long long ULL;
    typedef pair<int,int> P;
    const int INF = 0x3f3f3f3f;
    const LL LNF = 1e18;
    const int maxn =  120;
    const int maxm = 1e5 + 10;
    const double PI = acos(-1.0);
    const double eps = 1e-8;
    const int dx[] = {-1,1,0,0,1,1,-1,-1};
    const int dy[] = {0,0,1,-1,1,-1,1,-1};
    const int mon[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
    const int monn[] = {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
    int n,m;
    int v[maxm], w[maxm],dp[maxm];
    int t;
    bool vis[25][maxm];
    
    int main()
    {
        while(cin>>m>>n){
            memset(vis,0,sizeof(vis));
            memset(dp,0,sizeof(dp));
    
            for(int i=1;i<=n;i++)
                cin>>w[i];
    
            for(int i=n;i>=1;i--){ //输出倒序
                for(int j=m;j>=w[i];j--){ 
                     //dp[j]=max(dp[j],dp[j-w[i]]+w[i]); 
                     if(dp[j]<dp[j-w[i]]+w[i]){ 
                        dp[j]=dp[j-w[i]]+w[i]; 
                        vis[i][j]=true;
                     }
                }
            }
            for(int i=1,j=dp[m]; i<=n && j>0; i++){ 
                if(vis[i][j]){
                    cout<<w[i]<<' ';
                     j -= w[i];      
                }
            }
            cout<<"sum:"<<dp[m]<<endl;
        }
    }
    /*
    5 3 1 3 4
    10 4 9 8 4 2
    20 4 10 5 7 4
    90 8 10 23 1 2 3 4 5 7
    45 8 4 10 44 43 12 9 8 2
    */
    一维逆序
    #include<cstdio>
    #include<string>
    #include<cstdlib>
    #include<cmath>
    #include<iostream>
    #include<cstring>
    #include<set>
    #include<queue>
    #include<algorithm>
    #include<vector>
    #include<map>
    #include<cctype>
    #include<stack>
    #include<sstream>
    #include<list>
    #include<assert.h>
    #include<bitset>
    #include<numeric>
    #define debug() puts("++++")
    #define gcd(a,b) __gcd(a,b)
    #define lson l,m,rt<<1
    #define rson m+1,r,rt<<1|1
    #define fi first
    #define se second
    #define pb push_back
    #define sqr(x) ((x)*(x))
    #define ms(a,b) memset(a,b,sizeof(a))
    #define sz size()
    #define be begin()
    #define pu push_up
    #define pd push_down
    #define cl clear()
    #define lowbit(x) -x&x
    #define all 1,n,1
    #define rep(i,n,x) for(int i=(x); i<(n); i++)
    #define in freopen("in.in","r",stdin)
    #define out freopen("out.out","w",stdout)
    using namespace std;
    typedef long long LL;
    typedef unsigned long long ULL;
    typedef pair<int,int> P;
    const int INF = 0x3f3f3f3f;
    const LL LNF = 1e18;
    const int maxn =  120;
    const int maxm = 1e5 + 10;
    const double PI = acos(-1.0);
    const double eps = 1e-8;
    const int dx[] = {-1,1,0,0,1,1,-1,-1};
    const int dy[] = {0,0,1,-1,1,-1,1,-1};
    const int mon[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
    const int monn[] = {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
    /*
    5 3 1 3 4
    10 4 9 8 4 2
    20 4 10 5 7 4
    90 8 10 23 1 2 3 4 5 7
    45 8 4 10 44 43 12 9 8 2
    */
    int dp[25][maxm];
    int w[25],n,m;
    int main()
    {
        while(cin>>m>>n)
        {
            memset(dp,0,sizeof(dp));
            for(int i=1;i<=n;i++) cin>>w[i];
    
            for(int i=1;i<=n;i++)
            {
                for(int j=1;j<=m;j++) //注意是顺推
                {
                    if(j>=w[i]) dp[i][j]=max(dp[i-1][j], dp[i-1][j-w[i]]+w[i]);
                    else    dp[i][j]=dp[i-1][j]; //必须判断
                }
            }
    
            for(int i=n,j=m; i>0; i--)
            {
                if(dp[i][j]>dp[i-1][j]) //在顺推时考察第i是放还是不放是从前一个状态推出来的,如果放入i时大,说明放入了i,否则没放和前一个状态一样  
                {
                   cout << w[i] <<' ';
                    j -= w[i];
                }
            }
            cout << "sum:"<<dp[n][m]<<endl;
        }
    }
    二维顺推
    #include<cstdio>
    #include<string>
    #include<cstdlib>
    #include<cmath>
    #include<iostream>
    #include<cstring>
    #include<set>
    #include<queue>
    #include<algorithm>
    #include<vector>
    #include<map>
    #include<cctype>
    #include<stack>
    #include<sstream>
    #include<list>
    #include<assert.h>
    #include<bitset>
    #include<numeric>
    #define debug() puts("++++")
    #define gcd(a,b) __gcd(a,b)
    #define lson l,m,rt<<1
    #define rson m+1,r,rt<<1|1
    #define fi first
    #define se second
    #define pb push_back
    #define sqr(x) ((x)*(x))
    #define ms(a,b) memset(a,b,sizeof(a))
    #define sz size()
    #define be begin()
    #define pu push_up
    #define pd push_down
    #define cl clear()
    #define lowbit(x) -x&x
    #define all 1,n,1
    #define rep(i,n,x) for(int i=(x); i<(n); i++)
    #define in freopen("in.in","r",stdin)
    #define out freopen("out.out","w",stdout)
    using namespace std;
    typedef long long LL;
    typedef unsigned long long ULL;
    typedef pair<int,int> P;
    const int INF = 0x3f3f3f3f;
    const LL LNF = 1e18;
    const int maxn =  120;
    const int maxm = 1e5 + 10;
    const double PI = acos(-1.0);
    const double eps = 1e-8;
    const int dx[] = {-1,1,0,0,1,1,-1,-1};
    const int dy[] = {0,0,1,-1,1,-1,1,-1};
    const int mon[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
    const int monn[] = {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
    /*
    5 3 1 3 4
    10 4 9 8 4 2
    20 4 10 5 7 4
    90 8 10 23 1 2 3 4 5 7
    45 8 4 10 44 43 12 9 8 2
    */
    int dp[maxm],vis[maxm];
    int w[25],n,m;
    int main()
    {
        while(cin>>m>>n)
        {
            memset(dp,0,sizeof(dp));
            memset(vis,0,sizeof(vis));
            for(int i=1;i<=n;i++) cin>>w[i];
            for(int i=1;i<=n;i++)
            {
                for(int j=m;j>=w[i];j--) 
                {
                    if(dp[j] < dp[j-w[i]]+w[i])
                    {
                        dp[j] = dp[j-w[i]]+w[i];
                        vis[j] = vis[j-w[i]] | (1<<i);
                    }
                }
            }
    
            for(int i=1; i<=n; i++)
            {
                if(vis[m] & (1<<i))
                {
                    cout << w[i] << ' ';
                }
            }
            cout << "sum:"<<dp[m]<<endl;
        }
    }
    一维状态压缩
    #include<cstdio>
    #include<string>
    #include<cstdlib>
    #include<cmath>
    #include<iostream>
    #include<cstring>
    #include<set>
    #include<queue>
    #include<algorithm>
    #include<vector>
    #include<map>
    #include<cctype>
    #include<stack>
    #include<sstream>
    #include<list>
    #include<assert.h>
    #include<bitset>
    #include<numeric>
    #define debug() puts("++++")
    #define gcd(a,b) __gcd(a,b)
    #define lson l,m,rt<<1
    #define rson m+1,r,rt<<1|1
    #define fi first
    #define se second
    #define pb push_back
    #define sqr(x) ((x)*(x))
    #define ms(a,b) memset(a,b,sizeof(a))
    #define sz size()
    #define be begin()
    #define pu push_up
    #define pd push_down
    #define cl clear()
    #define lowbit(x) -x&x
    #define all 1,n,1
    #define rep(i,n,x) for(int i=(x); i<(n); i++)
    #define in freopen("in.in","r",stdin)
    #define out freopen("out.out","w",stdout)
    using namespace std;
    typedef long long LL;
    typedef unsigned long long ULL;
    typedef pair<int,int> P;
    const int INF = 0x3f3f3f3f;
    const LL LNF = 1e18;
    const int maxn =  120;
    const int maxm = 1e5 + 10;
    const double PI = acos(-1.0);
    const double eps = 1e-8;
    const int dx[] = {-1,1,0,0,1,1,-1,-1};
    const int dy[] = {0,0,1,-1,1,-1,1,-1};
    const int mon[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
    const int monn[] = {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
    /*
    5 3 1 3 4
    10 4 9 8 4 2
    20 4 10 5 7 4
    90 8 10 23 1 2 3 4 5 7
    45 8 4 10 44 43 12 9 8 2
    */
    int dp[maxm],vis[maxm];
    int w[25],n,m;
    void print(int i)
    {
        if(vis[i]){
            print(vis[i]);
            cout<<i-vis[i]<<' ';
        }
        else{
            cout<<i<<' ';
            return ;
        }
    }
    int main()
    {
        while(cin>>m>>n)
        {
            memset(dp,0,sizeof(dp));
            memset(vis,0,sizeof(vis));
            for(int i=1;i<=n;i++) cin>>w[i];
            for(int i=1;i<=n;i++)
            {
                for(int j=m;j>=w[i];j--)
                {
                    if(dp[j] < dp[j-w[i]]+w[i])
                    {
                        dp[j] = dp[j-w[i]]+w[i];
                        vis[j] = j - w[i];
                    }
                }
            }
            print(dp[m]);
            cout << "sum:"<<dp[m]<<endl;
        }
    }
    一维递归
  • 相关阅读:
    八步详解Hibernate的搭建及使用
    Hibernate的介绍
    javascript的优缺点和内置对象
    过滤器有哪些作用?
    JSP中动态INCLUDE与静态INCLUDE的区别?
    jsp的四种范围?
    jsp有哪些动作作用分别是什么?
    介绍在JSP中如何使用JavaBeans?
    jsp有哪些内置对象作用分别是什么 分别有什么方法?
    request.getAttribute() 和 request.getParameter() 有何区别?
  • 原文地址:https://www.cnblogs.com/Roni-i/p/9046085.html
Copyright © 2011-2022 走看看