重点是推出状态转移方程(递推式)
全局最优且前 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];
}