第16周总结

本周主要是看完了背包问题,自学了一点区间DP问题。

就目前看的博客,对于简单题,背包问题(01背包、完全背包、多重背包和)就是各自的套路,难得就是虽难,但比其他的DP简单。下面是几个自认为特别的题:


P1064 [NOIP2006 提高组] 金明的预算方案 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

这个题是01背包得变种,与普通的01背包区别是这个题的决策有不选、选主件、选主件和一个附件、选主件和另一个附件、选主件和两个附件共五种。只要想明白这个,这个题就很简单了。关键代码:

for(int i=1;i<=m;i++)
for(int i1=n;i1>=0;i1--)
{
if (i1>=a1[i]) 
		f[i1] = max(f[i1], f[i1-a1[i]]+b1[i]);
if (i1>=a1[i]+a2[i][2]) 
		f[i1] = max(f[i1], f[i1-a1[i]-a2[i][2]]+b1[i]+b2[i][2]);
if (i1>=a1[i]+a2[i][1]) 
		f[i1] = max(f[i1], f[i1-a1[i]-a2[i][1]]+b1[i]+b2[i][1]);
if (i1>=a1[i]+a2[i][1]+a2[i][2]) 
		f[i1] = max(f[i1], f[i1-a1[i]-a2[i][1]-a2[i][2]]+b1[i]+b2[i][1]+b2[i][2]);
}

P1091 [NOIP2004 提高组] 合唱队形 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

这个题一开始根本不知道怎么做,看了题解才明白,这种思维题真是不想明白就很难,想明白就变简单了。思路就是:正着求一遍最长上升子序列,再倒着求一遍最长上子序列,最后枚举相加求最大的那个,即:

for(int i=1;i<=n;i++) ans=max(f[0][i]+f[1][i]-1,ans);

 最后加一是因为左右都加了自己,自己一共加了两次,所以要减去一个。


P1387 最大正方形 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

这道题也是不看答案不知道怎么做。状态转移方程:

if(a[i][j]==1)f[i][j]=min(min(f[i][j-1],f[i-1][j]),f[i-1][j-1])+1; 

f[i][j]表示以(i,j)为右下角时,可构成的最大的正方形的边长。至于为什么这个转移方程是对的,我是看了几个别人举出来的例子和解释,就很明白了。对于这种与图形有关的题,也许以后在做不出来时需要在纸上画画图,这样可以更好的思考题。


Problem - 3466 (hdu.edu.cn)

这个题是个特殊的01背包,获得的价值与购买顺序有关。只要想明白这个,这题就很简单。做法只需要在01背包前根据Qi-Pi的差值从小到大排序。关键代码:

 sort(a+1,a+n+1,cmp);
 for(int i=1;i<=n;i++)
 for(int j=m;j>=a[i].q;j--)
 {dp[j]=max(dp[j],dp[j-a[i].p]+a[i].v);}

Proud Merchants详细解答 - MrMission - 博客园 (cnblogs.com)  这个讲的更详细。


真的是看得越多越觉得自己与他们差距很大,但之后也只有多看才能有所提高。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值