DP sets of questions Exercise 1

Preface: ① practice is not difficult, but there where noted.

Q1: Given AOE network engineering drawings, and engineering time required to complete the key in.

S1: First topological sorting [remember a queue, O (n) complexity], determine the sequence of DP (aftereffect) .DP apparently equation: f [to] = max (f [to], f [x] + val [to]). the key request the backstepping DP transfer process state.

Details: Note that the last possible effort to complete multiple routes at the same time, pay attention to deal with.

 

#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<queue>
using namespace std;
#define e exit(0)
#define R register
int n,cnt,cnt1,deep,ans,id,lenth,val[210],head[210],head1[210],rd[210],dl[210],cd[210],s[210][210],f[210],ask[210],vis[210];
struct bian{
    int to,next;
}len[210*210];
struct bian1{
    int to,next;
}len1[210*210];
void add(int from,int to)
{
    len[++cnt].to=to;
    len[cnt].next=head[from];
    head[from]=cnt;
}
void add1(int from,int to)
{
    len1[++cnt1].to=to;
    len1[cnt1].next=head1[from];
    head1[from]=cnt1;
}
void tpsort()
{
    queue<int> q;
    for(R int i=1;i<=n;++i)
        if(!rd[i]){
            q.push(i);
            dl[++deep]=i;
            f[i]=val[i];
        }
    while(q.size()){
        int now=q.front();
        q.pop();
        for(R int k=head[now];k;k=len[k].next){
            int to=len[k].to;
            --rd[to];
            if(rd[to]==0){
                dl[++deep]=to;
                q.push(to);
            }
        }
    }
    if(deep!=n){
        printf("-1");
        exit(0);
    }
}
void dfs(int x)
{
    for(R int k=head1[x];k;k=len1[k].next){
        int to=len1[k].to;
        if(f[x]==f[to]+val[x]){
            if(!vis[to]){
                ask[++lenth]=to;
                vis[to]=1;
                dfs(to);
            }
        }
    }
}
int main()
{
    freopen("project.in","r",stdin);
    freopen("project.out","w",stdout);
    scanf("%d",&n);
    for(R int i=1;i<=n;++i)
        scanf("%d",&val[i]);
    for(R int i=1;i<=n;++i)
        for(R int j=1;j<=n;++j)
            if(i!=j)
                s[i][++s[i][0]]=j;
    for(R int i=1;i<=n;++i){
        int to=i;
        for(R int j=1;j<=n-1;++j){
            int from=s[i][j],num;
            scanf("%d",&num);
            if(num==0) 
                continue;
            add(from,to),add1(to,from);
            ++rd[to];
            ++cd[from];
        }
    }
    tpsort();
    for(R int i=1;i<=deep;++i){
        int now=dl[i];
        for(R int k=head[now];k;k=len[k].next){
            int to=len[k].to;
            f[to]=max(f[to],f[now]+val[to]);
        }
    }
    for(R int i=1;i<=n;++i)
        if(!cd[i]){
            if(f[i]>ans)
                ans=f[i];
        }
    for(R int i=1;i<=n;++i)
        if(!cd[i]&&!vis[i]){
            if(f[i]==ans)
                ask[++lenth]=i,vis[i]=1;
        }
    printf("%d\n",ans);
    for(R int i=1;i<=lenth;++i)
        dfs(ask[i]);
    sort(ask+1,ask+1+lenth);
    for(R int i=1;i<=lenth;++i)
        printf("%d ",ask[i]);
    return 0;
}

 

Q2: Corporation has a highly efficient production equipment M units, ready to give under the N branches each branch if access to these devices, can provide some profit for the Corporation to ask: how to distribute this device to make national M the resulting profit maximum value calculated maximum profit allocation principles:? each company is entitled to any number of devices, but the total number of units shall not exceed the total number of devices M. Where M <= 100, N <= 100.

S2: Obviously linear DP, you can borrow ideas backpack, let f [i] [j] represents us before i companies were selected the maximum benefit j table set up with available enumerate the current opt-in the total number of devices k and on. the total number of primary station k, there will be a transfer equation f [i] [j] = max (f [i] [j], f [i - 1] [k] + val [j -k]) taken to initialize:. f [1] [j] = val [1] [j].

 

#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
#define e exit(0)
#define R register
int m,n,ans,f[110][110],val[110][110];
int main()
{
    freopen("machine.in","r",stdin);
    freopen("machine.out","w",stdout);
    scanf("%d%d",&m,&n);
    for(R int i=1;i<=n;++i)
        for(R int j=1;j<=m;++j)
            scanf("%d",&val[i][j]);
    for(R int j=1;j<=m;++j)
        f[1][j]=val[1][j];
    for(R int k=1;k<=n;++k)
        for(R int i=0;i<=m;++i)
            for(R int j=0;j<=i;++j)
                f[k][i]=max(f[k][i],f[k-1][j]+val[k][i-j]);
    for(R int j=0;j<=m;++j)
        ans=max(ans,f[n][j]);
    printf("%d",ans);
    return 0;
}

 

Q3: Given a string S, T given operation to replace, insert, delete, each one of which is carried out in one operation, ask how many operations a minimum of S becomes T..

S3: For DP between two strings, we usually set F [i] [j] denotes the front of the string S i bits xxx T j bits before operation, maintenance, max / min values ​​which we question. cis think this idea, provided F [i] [j] T becomes the first j bits of the bit string S i before the minimum number of operations if s [i] == t [j], f [i] [ j] = f [i-1] [j-1]. if s [i]! = t [j], then perform three operations .①f [i] [j] = min {f [i -1] [ j-1] +1}, a direct replacement .②f [i] [j] = min {f [i] [j-1] +1}, i represents a bit before the former becomes T, S j-1 bits, plus a .③f [i] [j] = min {f [i -1] [j] +1}, i-1 denotes the front of the first j bits into bit S T, and then a delete bit.

Details: Note that initialization, f [0] [j] = j, 0 bits j to j-bit operations obviously use.

 

#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
#define e exit(0)
#define R register
char s[1010],t[1010];
int lens,lent,f[1010][1010];
int main()
{
    freopen("edit.in","r",stdin);
    freopen("edit.out","w",stdout);
    scanf("%s",s+1),scanf("%s",t+1);
    lens=strlen(s+1),lent=strlen(t+1);
    memset(f,0x7f,sizeof(f));
    f[0][0]=0;
    for(R int i=1;i<=lens;++i)
        f[i][0]=i;
    for(R int j=1;j<=lent;++j)
        f[0][j]=j;
    for(R int i=1;i<=lens;++i)
        for(R int j=1;j<=lent;++j){
            if(s[i]==t[j])
                f[i][j]=f[i-1][j-1];
            else if(s[i]!=t[j]){
                f[i][j]=min(f[i][j],f[i-1][j-1]+1);
                f[i][j]=min(f[i][j],f[i][j-1]+1);
                f[i][j]=min(f[i][j],f[i-1][j]+1);
            }
        }
    printf("%d",f[lens][lent]);
    return 0;
}

 

Q4: n coins for face value, ask for a face value v, we have the minimum number of coins with it said that if you can not find the next smallest nominal value of v 'can be expressed, find the coin represents the number of coins can be reused.

S4: Obviously the module is fully backpack, we can change the definition, F [i] represents the minimum number of denominations of coins can be represented by i, f [i] = min {f [i -cost] +1} Note that the original initialization. f array of denominations are 1.

Details: When f [i-cost] == ​​0, this state is not valid, discarded.

 

#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
#define R register
int n,v,val[60],f[100010];
int main()
{
    freopen("coin.in","r",stdin);
    freopen("coin.out","w",stdout);
    scanf("%d%d",&n,&v);
    memset(f,0x7f,sizeof(f));
    for(R int i=1;i<=n;++i){
        scanf("%d",&val[i]);
        f[val[i]]=1;
    }
    for(R int i=1;i<=n;++i)
        for(R int j=val[i];j<=v;++j){
            if(f[j-val[i]]==0)
                continue;
            f[j]=min(f[j],f[j-val[i]]+1);
        }
    if(f[v]!=2139062143)
        printf("%d",f[v]);
    else if(f[v]==2139062143){
        for(R int i=v-1;i>=1;--i)
            if(f[v]!=2139062143){
                printf("%d",f[v]);
                break;
            }
    }
    return 0;
}

 

Guess you like

Origin www.cnblogs.com/xqysckt/p/11366583.html