
这题很暴力的一个DP,d[i][j]表示前i个数对选择一些Ai的和为j的最大Bi和。
状态转移方程:
dp[i][j]=max(dp[i][j],dp[i-1][j-sc[i].a]+sc[i].b);
AC代码
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int inf=1<<28; const int maxn=200002; int dp[101][maxn]; struct node{ int a,b; }sc[101]; int main(){ int n; while(scanf("%d",&n)==1){ for(int i=1;i<=n;++i){ scanf("%d%d",&sc[i].a,&sc[i].b); } for(int i=0;i<=n;++i) for(int j=0;j<maxn;++j) dp[i][j]=-inf; int ab=100000; for(int i=1;i<=n;++i){ dp[i][ab+sc[i].a]=sc[i].b; for(int j=0;j<maxn;++j){ dp[i][j]=max(dp[i-1][j],dp[i][j]); if(j-sc[i].a<=200000&&j-sc[i].a>=0) dp[i][j]=max(dp[i][j],dp[i-1][j-sc[i].a]+sc[i].b); } } int ans=0; int ind; for(int i=ab;i<maxn;++i){ if(dp[n][i]>=0&&dp[n][i]+i-ab>ans) { ans=dp[n][i]+i-ab; } } printf("%d\n",ans); } return 0; }
这个代码有两个可以优化的地方,第一个就是每次可以先把Ai和算出来,避免太多次的运算,空间上能够用滚动数组优化。
如有不当之处欢迎指出!