CodeForces - 808E-K - Selling Souvenirs-DP(像背包但不是背包)+优化技巧
2017-05-22 10:32
549 查看
http://codeforces.com/problemset/problem/808/E
给你单价 和价值,和背包大小,问你最优,不必填满。
单价1到3。。。。
裸的背包过不了。。
会tle。第15组数据 有50000个数,背包大小也为 53000多,过不了
too young too naive
看的题解,dp思路是先计算记录一下 1 和2的最优的情况。
(1和2先从大到小排序,有点贪心的意思,但是不能贪心性价比,因为背包问题就不能贪心性价比。。),
然后再枚举3的数量,找最大的。
后来我又改了一下,直接揭露三个数的最优情况,卡在一个特别大的数上。数量有100000,背包大小有 40000多。
应该是溢出了。
这个技巧很实用哈哈。
给你单价 和价值,和背包大小,问你最优,不必填满。
单价1到3。。。。
裸的背包过不了。。
会tle。第15组数据 有50000个数,背包大小也为 53000多,过不了
too young too naive
看的题解,dp思路是先计算记录一下 1 和2的最优的情况。
(1和2先从大到小排序,有点贪心的意思,但是不能贪心性价比,因为背包问题就不能贪心性价比。。),
然后再枚举3的数量,找最大的。
后来我又改了一下,直接揭露三个数的最优情况,卡在一个特别大的数上。数量有100000,背包大小有 40000多。
应该是溢出了。
这个技巧很实用哈哈。
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> using namespace std; /*裸背包会超时, 因为单价特别小,动态规划可以先处理一下 处理1 和2的情况 至于其他情况用前缀和就行。 */ const int maxn=300008; struct Node { long long v; int f,s,t; }; int cmp2(long long a,long long b) { return a>b; } int main() { int n,m; Node dp[maxn]; int a1,b1; int a[4][maxn]; long long sum[4][maxn]; int num[4]; memset(num,0,sizeof(num)); scanf("%d%d",&n,&m); for(int i=0;i<n;i++) { scanf("%d%d",&a1,&b1); a[a1][++num[a1]]=b1; } memset(sum,0,sizeof(sum)); for(int i=1;i<=3;i++) { sort(a[i]+1,a[i]+num[i]+1,cmp2); for(int j=1;j<=num[i];j++) sum[i][j]=sum[i][j-1]+a[i][j]; } /*for(int i=1;i<=3;i++) { for(int j=1;j<=num[i];j++) { printf("%d ",sum[i][j]); } cout<<endl; }*/ //dp[0].v=dp[0].s=dp[0].f=0; memset(dp,0,sizeof(dp)); for(int i=1;i<=m;i++) { dp[i]=dp[i-1]; if(dp[i-1].v+a[1][dp[i-1].f+1]>dp[i].v) { dp[i].v=dp[i-1].v+a[1][dp[i-1].f+1]; dp[i].f=dp[i-1].f+1; dp[i].s=dp[i-1].s; dp[i].t=dp[i-1].t; } if(i>=2&&dp[i-2].v+a[2][dp[i-2].s+1]>dp[i].v) { dp[i].v=dp[i-2].v+a[2][dp[i-2].s+1]; dp[i].f=dp[i-2].f; dp[i].s=dp[i-2].s+1; dp[i].t=dp[i-2].t; } /*if(i>=3&&dp[i-3].v+a[3][dp[i-3].t+1]>dp[i].v) {dp[i].v=dp[i-3].v+a[3][dp[i-3].t+1]; dp[i].f=dp[i-3].f; dp[i].s=dp[i-3].s; dp[i].t=dp[i-3].t+1; }*/ } long long ans=-1; for(int i=0;i<=num[3];i++) { if(m>=i*3) ans=max(ans,sum[3][i]+dp[m-3*i].v); } // cout<<dp[m].f<<" "<<dp[m].s<<endl; printf("%lld\n",ans); return 0; }
相关文章推荐
- codeforces 543A Writing Code(dp降维优化,完全背包思想)
- Codeforces 505C Mr. Kitayuta, the Treasure Hunter DP+技巧优化
- codeforces 543A A. Writing Code(完全背包优化dp )
- CodeForces 808E Selling Souvenirs(三分法/单调优化dp)
- Codeforces 55D Beautiful numbers 数位dp 数论 优化技巧
- CodeForces 543A - Writing Code DP 完全背包
- codeforces 148E Porcelain(DP, 分组背包)
- codeforces 148E Aragorn's Story 背包DP
- dp优化专辑 A - Starship Troopers [dp+背包]
- poj 1742 Coins(dp之多重背包+多次优化)
- hdu1059 dp(多重背包二进制优化)
- codeforces 167B Wizards and Huge Prize (概率dp,类似背包)
- Dividing(多重背包、单调队列优化dp)
- POJ 1014 Dividing 【DP 之 多重背包 / 二进制优化】
- codeforces 19B - Checkout Assistant DP 背包
- tyvj 1005 采药 0-1背包 优化的一位数组 dp 代码1
- hdu 2844 Coins(dp 多重背包 二进制优化)
- 【算法复习三】算法设计技巧与优化----各种背包问题总结
- hdu 5185 dp(完全背包)+优化
- 【算法复习三】算法设计技巧与优化----各种背包问题总结