UVA 624 CD (记录背包)

C - C
Time Limit:3000MS     Memory Limit:0KB     64bit IO Format:%lld & %llu
Submit  Status  Practice  UVA 624

Description


题意:

你即将开车出远门,当然希望在车上能聆听一些美好的音乐。你的车上只有播放录音带的设备,但是你最喜欢的音乐却都存放在CD上。所以你需要把CD上的音乐转录到录音带上。现在你必须解决的问题是:你的空白录音带长共N分钟,你如何选择CD上的歌使得尽可能的利用录音带的空间。以下是一些此问题的假设:

  • CD上的歌最多不会超过20首。
  • 没有任何一首歌的长度超过N分钟。
  • 要录在录音带上的歌不能重复。
  • 每首歌的长度以一整数表达。
  • N也是一个整数。

你的程式必须找出该放哪些CD上的歌到录音带上(按CD上的顺序),使得录音带空白的空间最小。

思路:典型0/1背包,打印路径不太会,wa了好几天,奉上我的代码 适合吾等菜鸟 看看:


1136242673 's source code for  C
Memory: 0 KB   Time: 0 MS
Language: C++ 4.8.2   Result: Accepted
Public:   No Yes

This source is shared by 1136242673

Select All
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<queue>
#include<cctype>
#define max(a,b)(a>b?a:b)
#define min(a,b)(a<b?a:b)
#define INF 0x3f3f3f3f

using namespace std;
int p[1100],dp[30][1100],v[1100],a[30];
int vis[30][1100];  /// 记录当dp[i][j]在动态转移时,==dp[i-1][j],则vis[i][j]=0,否则vis[i][j]=1

int main()
{
    int m,n,i,j,b;
    while(scanf("%d%d",&m,&n)!=EOF)
    {
        for(i=1; i<=n; i++)
        {
            scanf("%d",&p[i]);
        }

        memset(dp,0,sizeof(dp));
        memset(vis,0,sizeof(vis));

        for(i=1; i<=n; i++)
        {
            for(j=0; j<=m; j++)
            {
                if(j<p[i])
                {
                    dp[i][j]=dp[i-1][j];
                    vis[i][j]=0;
                }
                else
                {
                    if(dp[i-1][j]<dp[i-1][j-p[i]]+p[i])
                    {
                         dp[i][j]=dp[i-1][j-p[i]]+p[i];
                         vis[i][j]=1;
                    }
                    else
                    {
                        dp[i][j]=dp[i-1][j];
                        vis[i][j]=0;
                    }
                }
            }
        }

        j=m;
        b=0;
        for(i=n;i>0;i--)
        {
            if(vis[i][j]==1)
            {
                a[b++]=p[i];
                j=j-p[i];
            }
        }
        for(i=b-1;i>=0;i--)
            printf("%d ",a[i]);  ///  逆置 输出

        printf("sum:%d\n",dp[n][m]);
    }
    return 0;
}

 



你可能感兴趣的:(UVA 624 CD (记录背包))