摘要: 给定一个1….n的正整数序列,每次操作可以从序列寻找出一个或多个正整数,然后同时减去一个相同的正整数。通过画图可以发现只要把后一半都减去n/2就和前一半一样了,所以有递推式 f(n )=f(n/2) + 1#include using namespace std;int f(int n) { return n == 1 ? 1 : f(n >> 1) + 1;}int main() { int n; while(~scanf("%d",&n)) { printf("%d\n",f(n)); } return 0;} 阅读全文
posted @ 2014-02-09 13:12 acm_roll 阅读(198) 评论(0) 推荐(0) 编辑
摘要: 给你一个n*n的矩阵,你的任务是把尽量少的0变成1,使得每个数字的上下左右元素之和是偶数。直接暴力肯定会超时,找到行与行之间的关系,可以发现只要枚举第一行的所有情况,后面行都可以算出来。#include #include #include using namespace std;const int maxn = 16;const int INF = 2100000000 / 2;int mat[maxn][maxn],ans,n;int getsum(int x,int y,int m[maxn][maxn]) { int ans = 0; if(x > 1) ans += m[x - 阅读全文
posted @ 2014-02-09 13:08 acm_roll 阅读(185) 评论(0) 推荐(0) 编辑
摘要: 题意是一个圆桌上面做了n个人,每个人手头上有不同数目的金币(每个人手头的金币数目已知),然后他们需要通过相互交换来使得大家手头上面的金币数目相等,求最少流通值。白书上面用了一个非常强劲的代数做法,觉得这个思想还是需要学习一下的。因为人数和总的金币数是确定的,而且题目确保了一定除得进,所以最终情况下每个人手头的钱币数量是确定的,设为M,把人编号1,2,3,4,..n,设xi为编号i-1的人给编号为i的人的金币数,我们最终要求的值即为|x1|+|x2|+…+|xn|,Ai为每个人初始状况下手头的钱币数,有A1+x1-x2=M → x2=A1-M+x1 A2+x2-x3=M → x3=A2-M+x2 阅读全文
posted @ 2014-02-06 19:46 acm_roll 阅读(317) 评论(0) 推荐(0) 编辑
摘要: 题意是原本n个墓碑均匀分布在一个周长为10000的圆周上,现在加入m个,如果要使得n+m个墓碑都均匀分布的话,那么原来的墓碑最少的移动总距离是多少。因为加入m个之后m+n个墓碑的位置是固定的,要是移动距离最少必定会有一个墓碑不动,将圆周分成m+n段,分别标上0,1,2,3,4。。然后需要移动的墓碑坐标就是数轴上面的非整数点,两边的值靠近哪个就选哪个,之后再等比例扩大即可。#include #include #include using namespace std;int main() { int n,m; while(~scanf("%d%d",&n,&m) 阅读全文
posted @ 2014-02-06 19:17 acm_roll 阅读(497) 评论(0) 推荐(0) 编辑
摘要: 01背包问题,设f[i]为拿了i件能得到的最大价值。关于限制条件Q只要在每次更新f[i]的值的时候都判断当前值是否是小于Q的最大值即可#include #include #include using namespace std;const int maxn = 31;double f[maxn],val[400];int main() { int N; double Q; while(scanf("%lf%d",&Q,&N),N) { memset(f,0,sizeof(f)); double ans = 0; for(int i = 0;i 'C& 阅读全文
posted @ 2014-01-23 15:26 acm_roll 阅读(146) 评论(0) 推荐(0) 编辑
摘要: 题意大概是一个小哥要去抢银行,他列出了几个银行的价值和被抓概率,然后定了一个最高被抓概率,求最多可以抢多少价值的东西。一开始想成是被抓概率简单叠加了,写了个简单的背包就直接提交,WA..o(╯□╰)o不过确实是背包问题,不过求的值是逃跑概率,然后只要在能逃跑的范围内找最大价值就好了。#include #include #include using namespace std;double f[10001],p[150],P;int m[150];int main() { int T,n; scanf("%d",&T); while(T--) { int sum = 阅读全文
posted @ 2014-01-23 13:57 acm_roll 阅读(188) 评论(0) 推荐(0) 编辑
摘要: 一个典型的有依赖的背包问题。这里每种物品最多只可能有三个附属品,我看错了题目条件,写了一个可能有n个附属品的版本。o(╯□╰)o可以将物品按照附属关系先进行分组,对每组都来一次01背包。#include #include #include using namespace std;const int maxn = 100;const int maxv = 3201;struct Item { int cost,w,child,cnum[maxn],fa;};Item itm[maxn];int f[maxv],g[maxv];int main() { int n,limv; scanf(&quo 阅读全文
posted @ 2014-01-23 10:15 acm_roll 阅读(282) 评论(0) 推荐(0) 编辑
摘要: 最简单的RMQ问题,这次改用ST算法来写,存下来当模板吧。ST算法通过nlogn的时间(也可以是O(n))预处理出d[i][j](起始位置为i长度为2^(j-1))区间的内的最值,递推式:d[i][j] = min(d[i][j-1],d[I+2^(j-1][j-1])查询的时候先找到一个k有2^(k+1)>(R-L+1)然后可得minv(L,R)=min(d[L][K],d[R-(1#include #include #include using namespace std;const int maxn = 50001;int minv[maxn][20],maxv[maxn][20] 阅读全文
posted @ 2014-01-22 17:02 acm_roll 阅读(220) 评论(0) 推荐(0) 编辑
摘要: 大体思路就是枚举裁判位置,找逆序对数。练习一下用树状数组来寻找逆序对#include #include #include #define lowbit(x) ((x)&(-x))using namespace std;const int maxi = 100005;const int maxn = 20001;int C[maxi],num[maxn],n;int l[maxn],r[maxn];inline void add(int x,int d) { while(x 0) { ans += C[x]; x -= lowbit(x); } return ans;}int main( 阅读全文
posted @ 2014-01-21 15:28 acm_roll 阅读(325) 评论(0) 推荐(0) 编辑
摘要: 最裸的高精度幂,记录一下Java里面高精度类的用法而已 1 import java.io.*; 2 import java.util.Scanner; 3 import java.math.*; 4 5 public class Main 6 { 7 public static void main(String[] args) 8 { 9 Scanner cin = new Scanner(System.in);10 while(cin.hasNext()) {11 int m;12 String... 阅读全文
posted @ 2014-01-13 16:31 acm_roll 阅读(152) 评论(0) 推荐(0) 编辑