个人理解,就是dp过程中覆盖了某些数,运用这些数,又能在后续去更新某些数。
如:
L - Space Elevator
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
int k;
struct node{
int h;
int w;
int c;
}cow[410];
bool cmp(node a,node b)
{
return a.w<b.w;
}
int dp[40010];
int main(){
cin>>k;
for (int i=1;i<=k;i++)
{
cin>>cow[i].h>>cow[i].w>>cow[i].c;
}
sort(cow+1,cow+k+1,cmp);
dp[0]=1;
int use[40010];
int m=0;
for(int i=1;i<=k;i++)
{
memset(use,0,sizeof use);
for(int j=cow[i].h;j<=cow[i].w;j++)
{
if(!dp[j]&&dp[j-cow[i].h]&&use[j-cow[i].h]+1<=cow[i].c)
{
use[j]=use[j-cow[i].h]+1;
dp[j]=1;
if(j>m) m=j;
}
}
}
cout<<m<<endl;
return 0;
}
M - Cow Exhibition
#include<iostream>
#include<cstring>
using namespace std;
const int inf =1<<30;
int s[200],f[200];
int dp[200005];
int n;
int main()
{
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>s[i]>>f[i];
}
// memset(dp,-inf,sizeof dp);
for(int i=0;i<=200000;i++)
{
dp[i]=-inf;
}
dp[100000]=0;
for(int i=1;i<=n;i++)
{
if(s[i]<0&&f[i]<0) continue;
if(s[i]>0)
{
for(int j=200000;j>=s[i];j--)
{
if(dp[j-s[i]]>-inf)
{
dp[j]=max(dp[j],dp[j-s[i]]+f[i]);
}
}
}
else
{
for(int j=s[i];j<=s[i]+200000;j++)
{
if(dp[j-s[i]]>-inf)
{
dp[j]=max(dp[j],dp[j-s[i]]+f[i]);
}
}
}
}
int ans=-inf;
for(int i=100000;i<=200000;i++)
{
if(dp[i]>=0)
ans=max(ans,dp[i]+i-100000);
}
cout<<ans;
return 0;
}
F - Coins
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <iostream>
using namespace std;
int n,m;
int w[105],c[105],sum[100005],dp[100005]; //sum记录当前硬币使用情况
int main(){
while(~scanf("%d%d",&n,&m)) {
if(n==0&&m==0)break;
for(int i=0;i<n;i++)
scanf("%d",&w[i]);
for(int i=0;i<n;i++)
scanf("%d",&c[i]);
memset(dp,0,sizeof dp);
int ans=0;
dp[0]=1;
for(int i=0;i<n;i++)
{
memset(sum,0,sizeof sum);
for(int j=w[i];j<=m;j++)
{
if(!dp[j]&&dp[j-w[i]]&&sum[j-w[i]]<c[i])
{
dp[j]=1;
sum[j]=sum[j-w[i]]+1;
ans++;
}
}
}
cout<<ans<<endl;
}
return 0;
}