hihocoder#1044状态压缩dp+滚动数组
2015-10-02 00:34
585 查看
//20ms 0
#include<iostream> #include <string.h> #include <stdio.h> using namespace std; #define MAXN 1500 int N,M,Q; int dp[2][MAXN];//前一次的字母以及i的前面m个字母状态 int num[2][MAXN];//记录前m个字母中1的个数 int w[MAXN]; int main() { scanf("%d %d %d",&N,&M,&Q); for (int i=0;i<N;++i) scanf("%d",&w[i]); int ans = 0; memset(dp,-1,sizeof(dp)); for (int s=(1<<M)-1;s>=0;s--) { int nt = 0; int sums = 0; for (int i=0;i<M;++i) { if (s&(1<<i)) { nt++; sums+=w[i]; } } if (nt<=Q&&sums>dp[0][s]){ dp[0][s] = sums; num[0][s] = nt; } } //上一个M个数的状态 for (int i=M;i<N;++i) { for (int s=(1<<M)-1;s>=0;s--) { if (dp[0][s]>=0) { int cnt; if (s&(1<<0))//第一位是否选了 cnt = num[0][s]-1; else cnt = num[0][s]; int state = s>>1;//右移一位 //若不选该位置 dp[1][s>>1] =max(dp[1][s>>1],dp[0][s]); if (cnt<Q) dp[1][state|(1<<(M-1))] = max(dp[1][state|(1<<(M-1))],dp[0][s]+w[i]); } } memcpy(dp[0],dp[1],sizeof(dp[0])); memset(dp[1],-1,sizeof(dp[1])); } for (int s=(1<<M)-1;s>=0;s--) { if (dp[0][s]>ans) ans = dp[0][s]; } printf("%d\n",ans); return 0; }
相关文章推荐
- 动易2006序列号破解算法公布
- Ruby实现的矩阵连乘算法
- C#插入法排序算法实例分析
- 超大数据量存储常用数据库分表分库算法总结
- C#数据结构与算法揭秘二
- C#冒泡法排序算法实例分析
- C#使用DeflateStream解压缩数据文件的方法
- 算法练习之从String.indexOf的模拟实现开始
- C#算法之关于大牛生小牛的问题
- C#实现的算24点游戏算法实例分析
- C#调用WinRar执行rar、zip压缩的方法
- c语言实现的带通配符匹配算法
- 浅析STL中的常用算法
- 算法之排列算法与组合算法详解
- C++实现一维向量旋转算法
- Ruby实现的合并排序算法
- C#折半插入排序算法实现方法
- 基于C++实现的各种内部排序算法汇总
- C++线性时间的排序算法分析
- C++实现汉诺塔算法经典实例