UVA 12563(Jin Ge Jin Qu hao)

开始认真学DP。我对滚动数组的理解是:后一个状态可以由前一个状态求得,便可以使用一维数组重复利用节省空间复杂度。

这个题要注意题目要求的前提,求次数可以看作重量为v[i]价值为1放入w-1的背包,歌曲就是重量和价值都是v[i],简单的转化。

#include <iostream>
#include <bits/stdc++.h>

using namespace std;
const int maxn = 100000+10;
int dp[maxn];
int v[maxn];
int cnt[maxn];
int main()
{
    int t;
    cin >> t;
    int kase = 0;
    while(t--)
    {
        int n,w;
        cin >> n >> w;
        for(int i = 1 ; i <= n ; i ++)
            cin >> v[i];
        printf("Case %d:",++kase);
        memset(dp,0,sizeof(dp));
        memset(cnt,0,sizeof(cnt));
        for(int i = 1 ; i <= n ; i++)
        {
            for(int j = w-1 ; j >= v[i] ; j--)
            {
                if(cnt[j] < cnt[j - v[i]]+1)
                {
                   dp[j] = dp[j-v[i]]+v[i];
                   cnt[j] = cnt[j-v[i]]+1;                 
                }
                else if(cnt[j] == cnt[j-v[i]]+1)
                    dp[j] = max(dp[j],dp[j-v[i]]+v[i]);
            }
        }
        cout << " " << cnt[w-1]+1 << " " << dp[w-1]+678 << endl;
    }
    return 0;
}

 

posted @ 2017-05-13 00:31  萧萧Hsiao  阅读(135)  评论(0编辑  收藏  举报