uva--111History Grading +dp

题意:

其实就是求两个序列的最长公共子序列。

思路:

这个题目的输入是很坑爹的,如果把输入理解清楚后,这个题目就不难了。题目的输入表示的是该位置上的数放在哪个位置上,比如说输入是1,3,2,4其对应的序列应该是1,3,2,4;

下面给出2份代码,一份是经典的解法,一份是今天我写的把问题转成DAG图上的最长路求解的代码。

代码如下:

#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;

int d[30],n,map[30][30];

int dp(int i)
{
    if(d[i]>0) return d[i];
    d[i]=1;
    for(int j=1;j<=n;j++)
        if(map[i][j])
        {
            int t=dp(j)+1;
            if(d[i]<t)
                d[i]=t;
        }
    return d[i];
}

void Init()
{
    memset(d,0,sizeof(d));
    memset(map,0,sizeof(map));
}

int main()
{
    int i,j,a[30],b[30];
    while(scanf("%d",&n)!=EOF)
    {
         int x;
         for(i=1;i<=n;i++)
         {
             scanf("%d",&x);
             a[x]=i;
         }
         while(scanf("%d",&x)!=EOF)
         {
             Init(); b[x]=1;
             for(i=2;i<=n;i++)
             {
                 scanf("%d",&x);
                 b[x]=i;
             }
             for(i=1;i<=n;i++)
             {
                 for(j=1;j<=n;j++)
                    if(b[i]==a[j])
                        break;
                 for(int k=i+1;k<=n;k++)
                    for(int d=j;d<=n;d++)
                       if(b[k]==a[d])
                            map[i][k]=1;
             }
             int ans=0;
             for(i=1;i<=n;i++)
                ans=max(ans,dp(i));
             printf("%d\n",ans);
         }
    }
  return 0;
}

#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;

int main()
{
    int i,j,a[30],b[30],dp[30][30],n;
    while(scanf("%d",&n)!=EOF)
    {
         int x;
         for(i=1;i<=n;i++)
         {
             scanf("%d",&x);
             a[x]=i;
         }
         while(scanf("%d",&x)!=EOF)
         {
             b[x]=1;
             for(i=2;i<=n;i++)
             {
                 scanf("%d",&x);
                 b[x]=i;
             }
           memset(dp,0,sizeof(dp));
           for(i=1;i<=n;i++)
              for(j=1;j<=n;j++)
              {
                     if(a[i]==b[j])
                          dp[i][j]=dp[i-1][j-1]+1;
                     else
                           dp[i][j]=max(dp[i-1][j],dp[i][j-1]);
              }
              int ans=0;
              for(i=1;i<=n;i++)
                 for(j=1;j<=n;j++)
                      ans=max(ans,dp[i][j]);
              printf("%d\n",ans);
         }
    }
  return 0;
}
时间: 2024-12-11 10:43:47

uva--111History Grading +dp的相关文章

UVA - 111History Grading(LIS)

题目:UVA - 111History Grading(LIS) 题目大意:找最长的LIS.但是题意讲的实在是有问题. 例如:3 1 2 4 9 5 10 6 8 7,意思是第一个历史事件的时间是排在第三位,第二个历史事件是在第1位,那么首先先要将这个事件按照时间顺序重新排序.新的排列顺序:2 3 1 4 6 8 10 9 5 7. 解题思路:LIS. 代码: #include <cstdio> #include <cstring> #include <algorithm&g

Uva 111-History Grading(DP/LCS)

题目链接:点击打开链接 题意坑.. 本来一看就是就裸LCS ,但题目中给的输入并不是原序列,而是原序列,而是原序列的位置..比如 3 1 2 并不是 s[1]=3 而是1在序列中位置是3 即 s[3]=1; (s[x]=i;) 然后输入处理一下就裸LCS. #include <algorithm> #include <iostream> #include <cstring> #include <cstdlib> #include <string>

uva 12723 概率dp

Dudu is a very starving possum. He currently stands in the first shelf of a fridge. This fridge iscomposed of N shelves, and each shelf has a number Qi (1 ≤ i ≤ N) of food. The top shelf, whereDudu is, is identified by the number 1, and the lowest is

uva 11133 - Eigensequence(dp)

题目链接:uva 11133 - Eigensequence 题目大意:给定一个序列a,能够确定一个序列b,要求: 1)b[1]=a[1] 2)a[j?1]<b[j]≤a[j]且b[j]a[j]?a[j?1]为整数,j>1的时候 假设对于每一个ai=bi,则称b序列为Eigensequence序列. 如今给定a1和an,问有多少个Eigensequence序列. 解题思路:dp[i][j]表示第i个数为j的情况有多少种,假设k整除k-j,dp[i+1][k]+=dp[i][j]. #inclu

uva 11367 dijkstra+dp状态压缩

题意:给出n个地点 和 每个地点的油价 ,有 m 条边 , 并给出每条边长度 .1单位汽油可以走1千米  , 油箱的容量为 c , 在初始点 s 时 , 油箱中的油为 0 , 求s 到 t 的最小花费 . 解法: 定义 状态 d[i][j] 表示到达 地点 i 且油箱中有 j 单位油时的最小 花费. 对于状态的转移时 , 有两种方法: 1.把每个点的所有状态都求出 2.不把每个点的状态都求出 , 而是一单位一单位的加油. 对于第一种方法 , 会超时 , 因为每个点的状态太多 , 但是能用的状态就

uva 10593 - Kites(dp)

题目链接:uva 10593 - Kites 题目大意:给出一个n*n的图,表示一张纸板,问有多少种方法做成风筝,风筝必须是正方形或者是菱形,并且不能有洞. 解题思路:分正方形和菱形两种情况讨论: 正方形,dp[i][j]表示以i,j为右下角的正方形 dp[i][j]=min(dp[i?1][j],dp[i][j?1]) 并且如果黄色部分也为'x'的话,dp[i][j]++ 菱形,dp[i][j]表示菱形的正下角 同样地市黄色部分如果为'x'的话,dp[i][j]++ #include <cst

uva 10237 - Bishops(dp)

克里斯·厄姆森 谷歌今天在 Code 大会上发布了新的无人驾驶汽车.该汽车看起来像是有轮子的缆车,它既没有驾驶盘,也没有刹车踏板和加速装置.Re/code 采访了谷歌无人驾驶汽车项目主管克里斯·厄姆森(Chris Urmson),期间谈及该项目革命背后的概念.产品何时上路等问题. 谷歌在过去的 5 年里改装了现成车型去试验无人驾驶技术.除了车顶的旋转激光装置外,它们看上去跟普通车没什么不同.而该公司今天发布的汽车看上去则非常怪异.它们又小又圆,配备各种小型黑色传感器(车顶也有旋转激光装置),用泡

uva 674 (入门DP, 14.07.09)

 Coin Change  Suppose there are 5 types of coins: 50-cent, 25-cent, 10-cent, 5-cent, and 1-cent. We want to make changes with these coins for a given amount of money. For example, if we have 11 cents, then we can make changes with one 10-cent coin an

uva 1534 - Taekwondo(dp+贪心)

题目连接:uva 1534 - Taekwondo 题目大意:有两组什么东西,题目背景有点忘记了,就是给出两组数,两组个数分别为n,m,要求找出min(n,m)对数,每个数最多最多选一次,使得这min(n,m)对数ai,bi,ai-bi的绝对值之和最小. 解题思路:贪心,将两组数分别排序,然后dp[i][j]表示i对,匹配到j时候的最优解. #include <cstdio> #include <cstring> #include <cmath> #include &l

UVA 1534 - Taekwondo(dp)

题目链接:1534 - Taekwondo 题意:两组人比赛,一组n1人,一组n2人,选择min(n1,n2)组出来,要求两两人重量差绝对值之和最小. 思路:首先先预处理让n1变成人少的一组,人少的每个人都必须去匹配,dp[i][j] i表示n1组第i个人,j表示第二组多少人没匹配,于是匹配的时候n1组的第i人就和n2组的第i + j的人去匹配,然后进行状态转移 dp[i][j] = {dp[i - 1][k] + fabs(a1[i] - a2[i + j]), (0 <= k <= abs