hiho一下 第八周
来源:互联网 发布:剑三初始捏脸数据 编辑:程序博客网 时间:2024/05/18 20:09
题目:点击打开链接
动态规划+状态压缩
1.对于一个序列:1,2,3...i,只要知道i前面m-1个点的状况,就能推断出i可以选择1,或0。而前m-1个点每一种确定的状态又可能对应两种情况,第前m个是0或1.
这里i表示当前序列最后一个位置,j表示前m个点所有的情况。
如果前m-1个中1的个数等于q:dp[i][j/2]=max{dp[i-1][j]}; 最后一个点只能取1
如果前m-1个中1的个数等于q:dp[i][j/2+(1<<m)]=max{dp[i-1][j]}+w[i];
dp[i][j/2]=max{dp[i-1][j]};
这里写的比较朴素的代码:
#include<iostream>#include<cstdio>using namespace std;int w[1111], dp[1111][1111];int f(int x, int m){ int ans = 0; for(int i=1; i<=m; i++) { if(x%2==1) ans++; x/=2; } return ans;}int DP(int n, int m, int q){ for(int i=1; i<=n; i++) { for(int j=0; j<(2<<m); j++) { //如果前M-1个中选的个数小于Q if(f(j/2,m)<q) { dp[i][j/2+(2<<(m-1))] = max(dp[i][j/2+(2<<(m-1))], dp[i-1][j]+w[i]); dp[i][j/2] = max(dp[i][j/2], dp[i-1][j]); } else if(f(j/2,m)==q) { dp[i][j/2] = max(dp[i][j/2], dp[i-1][j]); } } } int ans = -1000000; for(int j=0; j<(2<<m); j++) { ans = max(ans, dp[n][j]); } return ans;}int main(){ int n,m,q; cin>>n>>m>>q; for(int i=1; i<=n; i++) cin>>w[i]; cout<<DP(n,m-1,q)<<endl; return 0;}
改进1:减少空间,dp[n][1<<m]可以缩减为d[2][1<<m],因为每次只要比较当前状态和前一个状态,只要用flag=0, flag^=1来处理就行了。
改进2:由于直接排出奇数的情况,for循环可以写成for(int j=0; j<(1<<m); j+=2)。
0 0
- hiho一下 第八周
- hiho一下 第八十八周
- hiho一下第八周(状态压缩)
- hihocoder: hiho一下 第八十八周 88
- hiho一下 第八十九周 Divisors
- hiho一下 第八十九周 Divisors
- hiho一下 第八十八周 Coordinates (求约数)
- hiho一下 第十五周
- hiho一下 第二周
- hiho一下 第三周
- hiho一下 第五十周
- hiho一下58周
- hiho一下第六十周
- hiho一下 第六十周
- hiho一下 第143周 hiho密码
- hiho一下 第四十八周
- hiho一下 第四十九周
- hiho一下 第五十六周
- XDOJ1055 - 魔兽争霸考试
- mysql error1064
- 上传几张智能开关产品图片
- C++设计模式之状态模式(四)
- 黑马程序员------IO操作总结(二)
- hiho一下 第八周
- Notepad++不保存文件打开历史与查找替换历史的方法
- 技术面试问题汇总第002篇:猎豹移动反病毒工程师part2
- 一网打尽!200+值得收藏的设计师资源站
- android开发之继承BaseAdapter实现通用数据适配器
- LeetCode N-Queens
- Leetcode 链表 Linked List Cycle II
- codeforces 463E Caisa and Tree 栈+dfs
- C# 基类 派生类 方法隐藏 方法重写