动态规划练习4
2017-07-27 13:04
183 查看
[b]买斧头[/b]
题目描述:
lw想买斧头了!他在商店里订购了n把斧头,但他身上只有k张信用卡,每个信用卡有一个价值,一张信用卡只能支付连续的一段斧头。但这个商店有一个奇怪的规则:不找零。即信用卡如果支付了一次还有余额,商店是不会退的(黑店)。现在lw想知道怎样安排信用卡的使用顺序,可以使剩下的信用卡的价值和最大(用了的不算)。
输入格式:
第一行两个数,分别为k和n,接下来k行,为每张信用卡的价值,接下来n行,为每一把斧头的价格。
输出格式:
如果存在方案能够支付,输出最大价值和(对于没用过的信用卡);如果方案不存在,则输出“hai you zhe zhong cao zuo?”(引号里的部分)
样例输入:buy.in
3 6
12
15
10
6
3
3
2
3
7
样例输出:buy.out
12(第二张支付前4把斧头,第三张支付剩下的,余下12)
数据范围:
对于30%的数据,k<=5,n<=20
对于100%的数据,k<=16,n<=100000
[b]题解:[/b]
[b]我们要维护两个值;[/b]
[b]f[i]是到i这个消费卡的使用状态最多能付多少奶牛的账单;[/b]
[b]g[i]是在f[i]最大前提下剩余的最多余额;[/b]
[b]由于在转移过程中要快速查找当前消费卡从当前位置开始能支付的最长序列;[/b]
[b]所以加上二分查找 T((1<<k)logn)[/b]
[b]设c为当前消费卡从当前位置开始能支付的最长序列的终点;[/b]
[b]那么就有以下方程[/b]
[b]if(c>f[i]||(c==f[i]&g[i-(1<<j-1)]-w[j]>g[i]))[/b]
[b]f[i]=c,g[i]=g[i-(1<<j-1)]-w[j];[/b]
题目描述:
lw想买斧头了!他在商店里订购了n把斧头,但他身上只有k张信用卡,每个信用卡有一个价值,一张信用卡只能支付连续的一段斧头。但这个商店有一个奇怪的规则:不找零。即信用卡如果支付了一次还有余额,商店是不会退的(黑店)。现在lw想知道怎样安排信用卡的使用顺序,可以使剩下的信用卡的价值和最大(用了的不算)。
输入格式:
第一行两个数,分别为k和n,接下来k行,为每张信用卡的价值,接下来n行,为每一把斧头的价格。
输出格式:
如果存在方案能够支付,输出最大价值和(对于没用过的信用卡);如果方案不存在,则输出“hai you zhe zhong cao zuo?”(引号里的部分)
样例输入:buy.in
3 6
12
15
10
6
3
3
2
3
7
样例输出:buy.out
12(第二张支付前4把斧头,第三张支付剩下的,余下12)
数据范围:
对于30%的数据,k<=5,n<=20
对于100%的数据,k<=16,n<=100000
[b]题解:[/b]
[b]我们要维护两个值;[/b]
[b]f[i]是到i这个消费卡的使用状态最多能付多少奶牛的账单;[/b]
[b]g[i]是在f[i]最大前提下剩余的最多余额;[/b]
[b]由于在转移过程中要快速查找当前消费卡从当前位置开始能支付的最长序列;[/b]
[b]所以加上二分查找 T((1<<k)logn)[/b]
[b]设c为当前消费卡从当前位置开始能支付的最长序列的终点;[/b]
[b]那么就有以下方程[/b]
[b]if(c>f[i]||(c==f[i]&g[i-(1<<j-1)]-w[j]>g[i]))[/b]
[b]f[i]=c,g[i]=g[i-(1<<j-1)]-w[j];[/b]
#include<iostream> #include<cstdio> #include<cstring> #include<cstdlib> #include<cmath> #include<algorithm> using namespace std; typedef long long lol; lol f[1<<16],t[17],n,m,a[17],b[100001],cnt,dp[1<<16],ans=-1,tot; lol gi() { lol ans=0,f=1; char i=getchar(); while(i<'0'||i>'9'){if(i=='-')f=-1;i=getchar();} while(i>='0'&&i<='9'){ans=ans*10+i-'0';i=getchar();} return ans*f; } lol suan(lol x,lol s) { lol l=x,r=m,ans=0; while(l<=r) { lol m=(l+r)>>1; if(b[m]-b[l-1]<=s) { ans=m; s-=b[m]-b[l-1]; l=m+1; } else r=m-1; } return ans; } int main() { freopen("buy.in","r",stdin); freopen("buy.out","w",stdout); lol i,j,k; n=gi();m=gi(); for(i=1;i<=n;i++){a[i]=gi();tot+=a[i];} for(i=1;i<=m;i++){b[i]=gi();b[i]+=b[i-1];} cnt=(1<<n)-1; for(i=1;i<=n;i++)t[i]=1<<(i-1); for(i=0;i<=cnt;i++) { for(k=1;k<=n;k++)if(!(i&t[k])) { lol p=suan(f[i]+1,a[k]); lol ka=i|t[k]; if(p>f[ka]) { f[ka]=p; dp[ka]=dp[i]+a[k]; if(p==m)ans=max(ans,tot-dp[ka]); } } } if(ans==-1)printf("hai you zhe zhong cao zuo?\n"); else printf("%lld\n",ans); return 0; }
相关文章推荐
- 算法练习笔记(十一)— 动态规划之分解问题
- 算法练习 动态规划 硬币找零
- 动态规划入门练习
- 练习3——动态规划总结
- HDU 5389 Zero Escape(动态规划)——多校练习8
- 动态规划练习 14
- 动态规划练习一 17:开餐馆
- 动态规划练习--09(移动路线)
- 动态规划练习19:最低通行费
- 动态规划初级练习(二):BadNeighbors
- 编程练习-动态规划(矩阵乘法)
- 每周算法练习——用动态规划求解最短路径问题
- leetcode 55 动态规划练习
- 动态规划练习 4
- 动态规划练习2--poj3616
- 2016-6-19 动态规划,贪心算法练习
- 动态规划练习一 10:数字组合
- 动态规划练习一 26:滑雪
- 动态规划练习一—26、30滑雪
- 动态规划练习21:三角形最佳路径问题