HDU1087题目大意: 给你一串序列,要求求出一个序列,必须是上升的,但是中途可以跳着走,比如1,3,7,6,8,11,5,6,7 那么你可以走1,3,7,8,11,也可以走1,3,6,8,11,还可以走1,3,5,6,7……然后要求这个求出的序列要最大。 解题思路: 用dp是比较好的选择。找出状态转移方程即可。
/*
*状态转移:dp[i] = max(dp[j] + num[i]); (1 <= j < i <= n, num[j] < num[i])
*/
#include
using namespace std;
const int MAX = 1005;
int main(void)
{
    int n;
    int dp[MAX], num[MAX];
    while(scanf("%d", &n), n)
    {
        for(int i = 1; i <= n; i++)
            scanf("%d", &num[i]);
        for(int i = 1; i <= n; i++)
        {
            dp[i] = num[i];
            for(int j = 1; j < i; j++)
            {
                if(num[j] < num[i])
                    dp[i] = max(dp[j] + num[i], dp[i]);
            }
        }
        int max = -1000000000;
        for(int i = 1; i <= n; i++)
        {
            if(dp[i] > max)
                max = dp[i];
        }
        printf("%d\n", max);
    }
    return 0;
}
HDU1160题目大意: 给你一串数据,每行数据两个数,第一个是老鼠的重量,第二个是老鼠的速度,然后要求求最长子序列满足,老鼠的重量递增,但是速度递减,中途可以跳过几个。 解题思路: 跟上面那道题目是一样的道理,只是这一道要求打印路径,路径,直接用栈打印就可以了 代码:
/*
*状态转移:dp[i] = max(dp[j]+1, dp[i])
*判断条件:(1 <= j < i <= n, fat[j].w > fat[i].w && fat[j].s < fat[i].s)
*/
#include
#include
#include
using namespace std;
const int MAX = 1005;
typedef struct fat
{
    int w, s;
    int index;
} F;

F fat[MAX];

bool cmp(F a, F b)
{
    if(a.w != b.w)
        return a.w < b.w;
    else
        return a.s > b.s;
}

int main(void)
{
    int s, w;
    int index = 0, dp[MAX], path[MAX];
    while(scanf("%d %d", &w, &s) == 2)
    {
        fat[index].index = index, fat[index].w = w, fat[index].s = s;
        index++;
    }
    memset(path, -1, sizeof(path));
    sort(fat, fat + index, cmp);

    for(int i = 0; i < index; i++)
    {
        dp[i] = 1;
        for(int j = 0; j < i; j++)
        {
            if(fat[j].w < fat[i].w && fat[j].s > fat[i].s)
            {
                if(dp[j] + 1 > dp[i]) //wa了两次,少加了这个条件,太可惜了,注意打路径的,要小心
                {
                    dp[i] = dp[j] + 1;
                    path[fat[i].index] = fat[j].index;
                }
            }
        }
    }
    int max = -1000000000, maxIndex = 0;
    for(int i = 0; i < index; i++)
    {
        if(dp[i] > max)
        {
            max = dp[i];
            maxIndex = i;
        }
    }

    //输出结果跟路径
    if(!index)
    {
        printf("0\n");
        exit(0);
    }
    stack pathS;
    int temp = fat[maxIndex].index;
    while(temp != -1)
    {
        pathS.push(temp);
        temp = path[temp];
    }

    printf("%d\n", max);
    while(!pathS.empty())
    {
        printf("%d\n", pathS.top() + 1);
        pathS.pop();
    }
    return 0;
}
posted on 2012-02-16 10:47  cchun  阅读(155)  评论(0编辑  收藏  举报