uva10154 - Weights and Measure(经典动归)

摞乌龟,,,

每只乌龟给出自身的重量和所能承受的重量,,让求最多摞起来的乌龟个数,,

思路:先将乌龟按照承受力(s[i]-w[i]),从小到大排序,,

然后从上向下计算已经被摞上乌龟的最小重量,,,

对于每个乌龟有两个状态,要或不要。。。

状态:dp[i][j]表示前i只乌龟摞成j层达到的最小重量。。。

状态转移:dp[i][j] = min(dp[i-1][j],dp[i-1][j-1]+w[i]);

代码如下;
#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;

#define M 5610
#define INF 0x7fffffff
int w[M], s[M], r[M], dp[M][M];
int comp(const int a, const int b){ return s[a]<s[b]; }
int main ()
{
    int n = 1;
    while(~scanf("%d%d",&w[n],&s[n])) { s[n] = s[n]-w[n]; n++; }
    n--;
    for(int i = 0; i <= n; i++) r[i] = i;
    sort(r+1,r+n+1,comp);
    for(int i = 0; i <= n; i++)
    {
        dp[i][0] = 0;
        for(int j = 1; j <= n; j++)
        dp[i][j] = INF;
    }
    for(int i = 1; i <= n; i++)
    for(int j = 1; j <= i; j++)
    {
        int x = r[i];
        dp[i][j] = dp[i-1][j];
        if(s[x]>=dp[i-1][j-1]&&dp[i-1][j-1]!=INF)
            dp[i][j] = min(dp[i-1][j],dp[i-1][j-1]+w[x]);
    }

    int ans;
    for(int i = n; i >= 1; i--)
        if(dp[n][i]!=INF) {ans = i; break;}
    printf("%d\n",ans);

    return 0;
}

你可能感兴趣的:(uva10154 - Weights and Measure(经典动归))