USACO Stringsobits 解题报告
来源:互联网 发布:windows office 密钥 编辑:程序博客网 时间:2024/04/30 11:09
可以直接移步这里:大神的代码http://belbesy.wordpress.com/2012/08/13/usaco-3-2-2-stringsobits/
这道题让求第I个N位数,要求这些数的二进制表达中1的个数小于L。
刚开始用暴力解法,从1开始递增,算每个数的二进制表达中1的个数,并计数。不出所料地通不过后面的大测试点。即使用了快速计算二进制中1的个数的方法(见代码)。
在看了大神的代码后开始使用动态规划的方法。
cnt[n][k] = cnt[n - 1][k] + cnt[n - 1][k - 1]
这个表达式的左侧表示n位二进制数其中1的个数小于等于k的个数。右边的表达式把这样的数分为两类:第n位为0的(第一部分)和第n位为1的(第二部分,剩下的n-1位至多有k-1个1)。
最后计算要求的数的时候从左往右逐位判断:
比如第n位,看后面n-1位满足条件的数的个数(cnt[n-1][k])是否大于I,如果是,则第n位是0,继续在后面n-1位组成的数中找(n-1位中有k个1的第I个数);如果不是,则说明要找的数第n位是1,把n位是0的满足条件的数的个数(cnt[n-1][k])减去(因为这些数小,排在前面),就是这个数在n位是1的满足条件的数中的排位,相当于接下来在n-1位中k-1个1的第I-cnt[n-1][k]个数。
代码如下,前面两个函数为求一个数中的二进制表达中1的个数的方法,第一个快于第二个,但都超时,因而用不上。
/*ID: thestor1LANG: C++TASK: kimbits*/#include <iostream>#include <cstdio>#include <cstring>#include <vector>#include <cassert>#include <string>#include <algorithm>using namespace std;int bitcount(unsigned int n) {/* works for 32-bit numbers only *//* fix last line for 64-bit numbers */register unsigned int tmp;//octal notationtmp = n - ((n >> 1) & 033333333333) - ((n >> 2) & 011111111111);return ((tmp + (tmp >> 3)) & 030707070707) % 63;}inline int cntones(int num){int cnt = 0;while(num > 0){num &= num - 1;cnt++;}return cnt;}string tobinary(unsigned int num, unsigned int width){string str;int w = 0;while(num > 0){str.push_back('0' + (num & 0x01));num >>= 1;w++;}string ret;for(int i = w; i < width; ++i){ret.push_back('0');}for(int i = str.length() - 1; i >= 0; --i){ret.push_back(str[i]);}return ret;}int main(){FILE *fin = fopen ("kimbits.in", "r");FILE *fout = fopen ("kimbits.out", "w");//freopen("log.txt", "w", stdout);unsigned int N, L, I;fscanf(fin, "%u%u%u", &N, &L, &I);unsigned int cnt[32][32] = {{0}};for(unsigned int n = 0; n <= N; ++n){cnt[n][0] = 1;cnt[0][n] = 1;}for(unsigned int n = 1; n <= N; ++n){for(unsigned int k = 1; k <= L; ++k){cnt[n][k] = cnt[n - 1][k] + cnt[n - 1][k - 1];}}unsigned int n = N, k = L;while(n > 0){fprintf(stdout, "cnt[%u - 1][%u] = %u, I = %u\n", n, k, cnt[n - 1][k], I);if(cnt[n - 1][k] >= I){fprintf(stdout, "%u\n", I);fprintf(fout, "0");n--;}else{fprintf(fout, "1");I -= cnt[n - 1][k];n--;k--;}}fprintf(fout, "\n");return 0;}
- USACO Stringsobits 解题报告
- USACO Stringsobits
- usaco Stringsobits
- USACO:Overfencing解题报告
- usaco Transformations 解题报告
- USACO Camelot 解题报告
- USACO Cowcycles 解题报告
- USACO Wormholes 解题报告
- USACO Telecowmunication 解题报告
- USACO Picture 解题报告
- USACO Twofive 解题报告
- USACO 3.4解题报告
- USACO 4.1解题报告
- USACO 4.2解题报告
- USACO 4.3解题报告
- USACO 4.4解题报告
- USACO 5.3解题报告
- USACO 6.1解题报告
- 对企业信息化的一些看法
- 安装、设置与启动MySql绿色版的方法
- strToInt和intToStr的自我定义
- STL总体说明
- HasnMap
- USACO Stringsobits 解题报告
- Python的一些学习笔记
- HashSet
- LINUX下C语言连接mysql
- STL之pair对组
- Qt Meta Object system 学习(一)
- JQGrid 里边Inline编辑时按 Esc 触发什么事件?【答案在这】
- linux进程管理学习笔记
- C++异常机制的实现方式和开销分析