acm 第八天:动态规划

重点是推出状态转移方程(递推式)
全局最优且前 i 步也最优

int maxsum(int x,int y)
{
    if(x==n) return mp[x][y];
    int sum1=maxsum(x+1,y);
    int sum2=maxsum(x+1,y+1);
    if(sum1>sum2) return sum1+mp[x][y];
    return sum2+mp[x][y];
}
cout<<maxsum(1,1)<<endl;

int maxsum(int x,int y)
{
    if(x==n) return mp[x][y];
    if(ans[x+1][y]==-1)//如果maxsum(x+1,y)没有计算过
        ans[x+1][y]=maxsum(x+1,y);
    if(ans[x+1][y+1]==-1)//如果maxsum(x+1,y+1)没有计算过
        ans[x+1][y+1]=maxsum(x+1,y+1);
    return max(ans[x+1][y],ans[x+1][y+1])+mp[x][y];
}
cout<<maxsum(1,1)<<endl;

     cin>>n;
    for(int i=1;i<=n;i++)
        for(int j=1;j<=i;j++)
            cin>>mp[i][j];
    for(int i=1;i<=n;i++)
        ans[n][i]=mp[n][i];
    for(int i=n;i>1;i--)
        for(int j=1;j<i;j++)
           ans[i-1][j]=max(ans[i][j],ans[i][j+1])+mp[i-1][j];
    cout<<ans[1][1]<<endl;

    cin>>n;
    for(int i=1;i<=n;i++)
        for(int j=1;j<=i;j++)
            cin>>mp[i][j];
    ans[1][1]=mp[1][1];
    for(int i=2;i<=n;i++)
        for(int j=1;j<=i;j++)
           ans[i][j]=max(ans[i-1][j-1],ans[i-1][j])+mp[i][j];
    int maxm=ans[n][1];
    for(int i=2;i<=n;i++)
        maxm=max(maxm,ans[n][i]);
    cout<<maxm<<endl;

 cin>>n;
    for(int i=1;i<=n;i++)
        for(int j=1;j<=i;j++)
            cin>>mp[i][j];
    ans[1]=mp[1][1];
    for(int i=2;i<=n;i++)
        for(int j=i;j>=1;j--)
           ans[j]=max(ans[j-1],ans[j])+mp[i][j];
    int maxm=ans[1];
    for(int i=2;i<=n;i++)
        maxm=max(maxm,ans[i]);
    cout<<maxm<<endl;

int ans=1;
    dp[1]=1;
    for(int i=2;i<=n;i++)
    {
        for(int j=1;j<i;j++)
            if(a[i]>a[j])
                dp[i]=max(dp[i],dp[j]+1);
        ans=max(ans,dp[i]);
    }
    cout<<ans<<endl;

 for(int i=0;i<n;i++)
    for(int j=0;j<m;j++)
    {
        if(s1[i]==s2[j]) dp[i+1][j+1]=dp[i][j]+1;
        else dp[i+1][j+1]=max(dp[i+1][j],dp[i][j+1]);
    }
printf("%d\n",dp[n][m]);

#include<bits/stdc++.h>
using namespace std;
int dp[1000010],n,m,k,t;
int main()
{
    int i,j;
    scanf(%d%d”,&n,&m);
    while(n--)
    {
        scanf("%d%d",&k,&t);
        for(i=m;i>=k;i--)dp[i]=max(dp[i],t+dp[i-k]);
    }
    printf("%d\n",dp[m]);
    return 0;
}

#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+10;
int n,m,dp[maxn];
int main()
{
    int i,j,k,t;
    scanf("%d%d",&n,&m);
    while(n--)
    {
        scanf("%d%d",&j,&k);
        for(i=j;i<=m;i++)dp[i]=max(dp[i],dp[i-j]+k);
    }
    printf("%d\n",dp[m]);
    return 0;
}

二进制优化

 for(int i=1;i<=n;i++)
{
        int k=1;     //对于每一种,k准备取1 2 4 8...
        int temp=a[i];  //a[i]为第i种的数量
        for(k; k<=temp ; k*=2)
        {
            value[++num]=k*v[i];  //v[i]为第i种的每个的价值
            temp-=k;
        }
        if(temp>0)
            value[++num]=temp*v[i];  
}

猜你喜欢

转载自blog.csdn.net/weixin_42748371/article/details/86560195