题意:给定一堆2二进制砝码,给定一个物品,要求在天平两端加入物品和砝码使之平衡,求可能数。

思路:一开始想到了直接用数学原理,结果没证出来。做如下思考,此题需要用二进制:

(1)设物品重量为w,加入的砝码重量为x,另一边重量为y,便有w+x=y。

(2)另外,假如物品为100110,加入的砝码可以为000010,那么总和为101000,显然x与y不能有位数相同的1(因为每种砝码只有一个),因此便有x&y=0

依据这两点,可以知道此题的关键之处就在于如何分析w+x的进位情况。分析物品的第i位,比如为1,那么如果前面的一位没有进位,那么他便可以加上1或者不加;如果进位,那就肯定不能加1(因为加1以后与进位的1加上这一位的结果还是1,与x&y=0矛盾),所以对于每一位,它的进位与不进位情况需要分开判断。

DP思路:设f[i][0]表示判断到i位时它不进位的情况数,f[i][1]表示到i位时它进位的情况数,都是从低位到高位判断。

(1)先考虑f[i][0](不进位的情况)

  • i位为1,如果前面不进位,那么这一位只能加上0才满足不进位的情况;如果前面进位,那么无论如何不可能使这一位不进位,因此f[i][0]=f[i-1][0];
  • i位为0,如果前面不进位,那么这一位只能选择0(因为选择加1的话将会与x&y=0矛盾);如果前面进位,那么这一位也只能选择0才能使i位也不进位,因此有f[i][0]=f[i-1][0]+f[i-1][1];

(2)再考虑f[i][1](进位的情况)

  • i位为1,如果前面不进位,那么这一位只能选择1才能使i位进位;如果前面进位,那么只能选择0使之进位(如果选择1那么结果将会与x&y=0矛盾),因此f[i][1]=f[i-1][0]+f[i-1][1];
  • i位为0,如果前面不进位,那么这一位无论如何不可能进位;如果前面进位,那么只能选择1才能使i位进位,因此f[i][1]=f[i-1][1];

这样,DP方程就得到了

if(s[i] == ){
f[i][] = f[i-][];
f[i][] = f[i-][]+f[i-][];
}
else{
f[i][] = f[i-][]+f[i-][];
f[i][] = f[i-][];
}

注意:不得不说,这个题目挺不错的,此题中间结果可能会超出long long,因此需要分次数判断,因为这个点我WA了N次

#include <iostream>
#include <string>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <memory>
#include <cmath>
#include <bitset>
#include <queue>
#include <vector>
#include <stack>
using namespace std; #define CLR(x,y) memset(x,y,sizeof(x))
#define MIN(m,v) (m)<(v)?(m):(v)
#define MAX(m,v) (m)>(v)?(m):(v)
#define ABS(x) ((x)>0?(x):-(x))
#define rep(i,x,y) for(i=x;i<y;++i) const int MAXN = 1100000; int t,n,m,d;
int s[MAXN];
int dp[MAXN][2]; void Solve()
{
char c; scanf("%d",&t);
while(t--)
{
scanf("%d%d%d",&n,&m,&d);
getchar();
CLR(s,0);
for(int i = m-1; i >= 0; --i){
scanf("%c",&c);
s[i] = c-'0';
}
if(s[0] == 0) {
dp[0][0] = 1;
dp[0][1] = 0;
}
else{
dp[0][0] = 1;
dp[0][1] = 1;
}
for(int i = 1; i < n; ++i){
if(s[i] == 1){
dp[i][0] = dp[i-1][0];
dp[i][1] = dp[i-1][0]+dp[i-1][1];
}
else{
dp[i][0] = dp[i-1][0]+dp[i-1][1];
dp[i][1] = dp[i-1][1];
}
if(dp[i][0]>=d) dp[i][0]-=d;
if(dp[i][1]>=d) dp[i][1]-=d;
}
cout<<(dp[n-1][0])<<endl;
}
} int main()
{
Solve();
return 0;
}

{POJ}{3971}{Scales}{O(N)动态规划}的更多相关文章

  1. POJ.3172 Scales (DFS)

    POJ.3172 Scales (DFS) 题意分析 一开始没看数据范围,上来直接01背包写的.RE后看数据范围吓死了.然后写了个2^1000的DFS,妥妥的T. 后来想到了预处理前缀和的方法.细节以 ...

  2. POJ 1163 The Triangle(简单动态规划)

    http://poj.org/problem?id=1163 The Triangle Time Limit: 1000MS   Memory Limit: 10000K Total Submissi ...

  3. [POJ 1787]Charlie's Change (动态规划)

    题目链接:http://poj.org/problem?id=1787 题意:有4种货币分别是1元,5元,10元,20元.现在告诉你这四种货币分别有多少个,问你正好凑出P元钱最多可以用多少货币.每种货 ...

  4. POJ 1080 Human Gene Functions -- 动态规划(最长公共子序列)

    题目地址:http://poj.org/problem?id=1080 Description It is well known that a human gene can be considered ...

  5. POJ 1050 To the Max -- 动态规划

    题目地址:http://poj.org/problem?id=1050 Description Given a two-dimensional array of positive and negati ...

  6. POJ 1458 Common Subsequence (动态规划)

    题目传送门 POJ 1458 Description A subsequence of a given sequence is the given sequence with some element ...

  7. POJ - 1163 The Triangle 【动态规划】

    一.题目 The Triangle 二.分析 动态规划入门题. 状态转移方程$$DP[i][j] = A[i][j] + max(DP[i-1][j], DP[i][j])$$ 三.AC代码 1 #i ...

  8. [ACM_动态规划] POJ 1050 To the Max ( 动态规划 二维 最大连续和 最大子矩阵)

    Description Given a two-dimensional array of positive and negative integers, a sub-rectangle is any ...

  9. POJ 3172 Scales (01背包暴力)

    题意:给定 n 个数,保证下一个数比上一个数和前一个数之和大,然后给定一个背包,问你最多放多少容积. 析:应该是很明显的01背包,但是可惜的是,数组开不出来,那就得考虑暴力,因为数不多,才几十而已,要 ...

随机推荐

  1. 使用7-zip制作自解压安装包

    7-zip制作自解压包很方便,只要在压缩时选择”创建自释放程序”选项. 而自解压安装包有点麻烦,不如WinRAR方便. 准备工具:下载 LZMA SDK 这里面有 7zSD.sfx (16.04版7z ...

  2. 单例实现c++

    #include <iostream> using namespace std; class Singleton { public: static Singleton *GetInstan ...

  3. Python的第四天

    函数 函数是组织好的,可重复使用的,用来实现单一,或相关联功能的代码段. 函数能提高应用的模块性,和代码的重复利用率.你已经知道Python提供了许多内建函数,比如print().但你也可以自己创建函 ...

  4. AJAX怎么用POST 传参数

    //注册回调函数.注意注册回调函数是不能加括号,加了会把函数的值返回给onreadystatechange xmlhttp.onreadystatechange = callback; //设置连接信 ...

  5. jsgen 搭建

    1,mongodb 2,redis  http://www.cnblogs.com/lxx/archive/2013/06/04/3116985.html http://blog.csdn.net/w ...

  6. angular(3)服务 --注入---自定义模块--单页面应用

    ng内部,一旦发生值改变操作,如$scope.m=x,就会自动轮询$digest队列,触发指定的$watch,调用其回调函数,然后修改dom树. 干货:https://github.com/xufei ...

  7. Intent传递List和Object和List<Object>

    一.传递List 传递List<String>的方法 小技巧,List<object> 可以使用json 转为 List<string>,就可以使用 List< ...

  8. MVC部分视图含义

    Partail Views 类似于ASPX视图引擎中的用户控件,使用部分视图可以创建放置于不同页面的通用部分.

  9. css3画三角形的原理

    以前用过css3画过下拉菜单里文字后面的“下拉三角符号”,类似于下面这张图片文字后面三角符号的效果 下面是一个很简单的向上的三角形代码 #triangle-up { width: 0; height: ...

  10. [源码]ObjectIOStream 对象流 ByteArrayIOStream 数组流 内存流 ZipOutputStream 压缩流

    1.对象流 import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.File ...