动态规划部分问题

动态规划

背包问题

if(j-a[i]>=0)
dp[i][j]=max(dp[i-1][j-a[i]]+b[i],dp[i-1][j]);
else 
    dp[i][j]=dp[i-1][j];
01背包
#include
using namespace std;
const int N=10010;
int dp[N][N];
int a[N],b[N];

int main()
{
    int n,v;
	cin>>n>>v;
	for(int i=1;i<=n;i++)
	{
		cin>>a[i]>>b[i];
	}	
// 	for(int i=0;i<=v;i++) dp[0][i]=0;
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=v;j++)
		{
			if(j-a[i]>=0) dp[i][j]=max(dp[i-1][j-a[i]]+b[i],dp[i-1][j]);     
			else          dp[i][j]=dp[i-1][j];
			
		}
	}
	cout<
###### 完全背包问题
#include
#include
#include
using namespace std;
const int u=10010;
int dp[u][u];
int a[u],b[u];
int main()
{
	int n,v;
	scanf("%d %d",&n,&v);
	for(int i=1;i<=n;i++)
	cin>>a[i]>>b[i];
	for(int i=1;i<=n;i++)
	{
		for(int j=0;j<=v;j++)
		{
			if(j-a[i]>=0)
			dp[i][j]=max(dp[i][j-a[i]]+b[i],dp[i-1][j]);
			else 
			dp[i][j]=dp[i-1][j];
		}
	}
	cout<
多重背包问题(二进制优化)
#include
using namespace std;
const int N=3e4+10;
int dp[N],v[N],w[N];
int n,m;
int main()
{
    cin>>n>>m;
    int cnt=1;
    for(int i=1;i<=n;i++)
    {
        int a,b,c;
        scanf("%d%d%d",&a,&b,&c);
        int k=1;
        while(k0)
            v[cnt]=c*a,w[cnt++]=c*b;
    }
    for(int i=1;i<=cnt;i++)
        for(int j=m;j>=v[i];j--)
                dp[j]=max(dp[j],dp[j-v[i]]+w[i]);
    cout<
完全背包问题
#include 
#include 

using namespace std;

const int N = 1010;

int n, m;
int v[N], w[N];
int f[N];

int main()
{
    cin >> n >> m;
    for (int i = 1; i <= n; i ++ ) cin >> v[i] >> w[i];

    for (int i = 1; i <= n; i ++ )
        for (int j = v[i]; j <= m; j ++ )
            f[j] = max(f[j], f[j - v[i]] + w[i]);

    cout << f[m] << endl;

    return 0;
}
分组背包问题
#include 
#include 

using namespace std;

const int N = 110;

int n, m;
int v[N][N], w[N][N], s[N];
int f[N];

int main()
{
    cin >> n >> m;

    for (int i = 1; i <= n; i ++ )
    {
        cin >> s[i];
        for (int j = 0; j < s[i]; j ++ )
            cin >> v[i][j] >> w[i][j];
    }

    for (int i = 1; i <= n; i ++ )
        for (int j = m; j >= 0; j -- )
            for (int k = 0; k < s[i]; k ++ )
                if (v[i][k] <= j)
                    f[j] = max(f[j], f[j - v[i][k]] + w[i][k]);

    cout << f[m] << endl;

    return 0;
}

线性DP

有明显的线性关系去求解

动态规划

1.状态表示(1)集合:所有从起点走到ij的路径。(2)属性:max,min,数量;

2.状态计算

例题,数字三角形

#include
#include
#include
#include
using namespace std;
const int N=510;
int g[N][N];
int dp[N][N];
int main()
{
	int n;
	cin>>n;
	for(int i=1;i<=n;i++)
		for(int j=1;j<=i;j++)
			scanf("%d",&g[i][j]);
	int ans=-1e9;
	for(int i=0;i<=n;i++)
        for(int j=0;j<=i+1;j++)
        dp[i][j]=-1e9;
    dp[1][1]=g[1][1];    
	for(int i=2;i<=n;i++)
	{
		for(int j=1;j<=i;j++)
		{
			dp[i][j]=max(dp[i-1][j-1]+g[i][j],dp[i-1][j]+g[i][j]);
		}
	}
	for(int i=1;i<=n;i++)
			ans=max(ans,dp[n][i]);
    printf("%d",ans);
	return 0;
}

你可能感兴趣的:(动态规划,算法)