zoukankan      html  css  js  c++  java
  • UVA 1424 uvalive 4256 Salesmen 简单DP

    题意:

    给一个无向连通图,和一个长度为L的序列。任务是修改序列上的某些数使得每相邻两个数相等或在图上是两个相邻的点。最少需要修改几个数?

    用dp[n][fa]表示当第n+1个数是fa时前n个数最少要修改几次

    用邻接矩阵存图,补上g[i][i]=1;g[0][i]=1;就可以不用分别考虑相等和初始的状态了

    dp[n][fa]=min{dp[n-1][v]+(v==an?0:1) | g[fa][v]==1 }

    int g[110][110];
    int da[210];
    int dp[210][110];
    int f(int n,int fa,int N)
    {
        if(dp[n][fa]>=0)return dp[n][fa];
        if(n==0)return 0;
        int num=INF;
        for(int i=1;i<=N;i++)
        {
            if(g[i][fa])
            {
                num=min(num,f(n-1,i,N)+(i==da[n]?0:1));
            }
        }
        return dp[n][fa]=num;
    }
    int main()
    {
        int t;
        scanf("%d",&t);
        for(int ca=1;ca<=t;ca++)
        {
            memset(g,0,sizeof(g));
            int n1,n2;
            scanf("%d%d",&n1,&n2);
            for(int i=1;i<=n2;i++)
            {
                int a,b;
                scanf("%d%d",&a,&b);
                g[a][b]=g[b][a]=1;
            }
            for(int i=1;i<=n1;i++)g[0][i]=g[i][0]=1;
            for(int i=1;i<=n1;i++)g[i][i]=1;
            int n3;
            scanf("%d",&n3);
            for(int i=1;i<=n3;i++)scanf("%d",&da[i]);
            memset(dp,-1,sizeof(dp));
            int num=f(n3,0,n1);
            printf("%d
    ",num);
        }
        return 0;
    }
    View Code
  • 相关阅读:
    [HDU 2089]不要62
    [WC 2011]Xor
    [BJOI 2011]元素
    [NOIp 2014]解方程
    [UVa 1326]Jurassic Remains
    [BZOJ 2152]聪聪可可
    [IOI 2011]Race
    [测试题]打地鼠
    [POJ 2828]Buy Tickets
    [测试题]gene
  • 原文地址:https://www.cnblogs.com/BMan/p/3250262.html
Copyright © 2011-2022 走看看