HIT暑期集训 区间DP,树形DP

A    POJ 1390

题解见:https://blog.csdn.net/qq_37708702/article/details/81944296

(DP这玩意我真是不大懂。。慢慢磨吧。。

C    POJ 3042

f[i][j][0]表示区间[i, j]已经遍历完,目前在i点时的最小值。f[i][j][1]表示区间[i, j]已经遍历完,目前在j点时的最小值。

在更新区间[i,j]时,有n-(j-i)个点的staleness在变化,分四种情况进行状态转移。

#include<cstdio>
#include<cstring>
#include<algorithm> 
#define maxn 1005
#define inf 0x3fffffff
using namespace std;
int a[maxn],f[maxn][maxn][2];
int main()
{
    int i,j,k,n,L,ans,tmp,pos;
    scanf("%d%d",&n,&L);
    for (i=1;i<=n;i++) scanf("%d",&a[i]);
    a[++n]=L;
    sort(a+1,a+n+1);
    for (i=1;i<=n;i++)
        if (a[i]==L) pos=i;
    for (i=1;i<=n;i++)
    for (j=1;j<=n;j++)
        f[i][j][0]=f[i][j][1]=inf;
    f[pos][pos][0]=f[pos][pos][1]=0;
    for (i=pos;i>=1;i--)
    for (j=pos;j<=n;j++)
    {
        tmp=n-(j-i);
        f[i][j][0]=min(f[i][j][0],f[i+1][j][0]+(a[i+1]-a[i])*tmp);
        f[i][j][0]=min(f[i][j][0],f[i+1][j][1]+(a[j]-a[i])*tmp);
        f[i][j][1]=min(f[i][j][1],f[i][j-1][1]+(a[j]-a[j-1])*tmp);
        f[i][j][1]=min(f[i][j][1],f[i][j-1][0]+(a[j]-a[i])*tmp);
    }
    if (f[1][n][0]<f[1][n][1]) ans=f[1][n][0];
    else ans=f[1][n][1];
    printf("%d
",ans);
    return 0;
}
View Code

F    POJ 2152

题解见:https://www.cnblogs.com/qzqzgfy/p/5553912.html

#include<cstdio>
#include<cstring>
#include<algorithm>
#define maxn 1005 
#define inf 99999999
using namespace std;
int num,last[maxn];
int dis[maxn],f[maxn][maxn],best[maxn];
int n,w[maxn],d[maxn];
struct edge
{
    int to,val,nxt;
}e[maxn<<1];
void add(int x,int y,int z)
{
    e[++num].to=y;
    e[num].val=z;
    e[num].nxt=last[x];
    last[x]=num;
}
void dfs_getdis(int u)
{
    int i,v;
    for (i=last[u];i!=-1;i=e[i].nxt)
    {
        v=e[i].to;
        if (dis[v]!=-1) continue;
        dis[v]=dis[u]+e[i].val;
        dfs_getdis(v);
    }
}
void dfs(int u,int fa)
{
    int i,j,v;
    for (i=last[u];i!=-1;i=e[i].nxt)
    {
        v=e[i].to;
        if (v==fa) continue;
        dfs(v,u);
    } 
    for (i=1;i<=n;i++) dis[i]=-1;
    dis[u]=0;
    dfs_getdis(u);
    for (i=1;i<=n;i++) f[u][i]=inf;
    best[u]=inf;
    for (i=1;i<=n;i++)
        if (dis[i]<=d[u])
        {
            f[u][i]=w[i];
            for (j=last[u];j!=-1;j=e[j].nxt)
            {
                v=e[j].to;
                if (v==fa) continue;
                f[u][i]+=min(best[v],f[v][i]-w[i]);
            }
            best[u]=min(best[u],f[u][i]);
        }
}
int main()
{
    int T,x,y,z,i;
    scanf("%d",&T);
    while (T--)
    {
        num=-1;
        memset(last,-1,sizeof(last));
        scanf("%d",&n);
        for (i=1;i<=n;i++) scanf("%d",&w[i]);
        for (i=1;i<=n;i++) scanf("%d",&d[i]);
        for (i=1;i<n;i++)
        {
            scanf("%d%d%d",&x,&y,&z);
            add(x,y,z);
            add(y,x,z);
         } 
         dfs(1,0);
         printf("%d
",best[1]);
    }
    return 0;
}
View Code

G    UVALive 4015

H    Gym 101667A

I    Gym 101667A

原文地址:https://www.cnblogs.com/lsykk/p/13519999.html