屯题大法好

CF 535C Tavas and Karafs

题目大意:给你一个无限长的等差数列,每次给一个起点L,可以吃T轮,每可以把M个数吃一口(-1),问最大的R使得区间[L,R]被吃完

思路:显然给定一个区间[L,R]后很容易贪心出能不能被吃完,并且发现该性质有单调性也就是如果[L,R]可以吃完,那[L,R-1]也可以,且存在最大的R使得[L,R+1]不满足条件,于是二分一下就可以了

 1 #include<iostream>
 2 #include<cstdio>
 3 #define ll long long
 4 using namespace std;
 5 ll a,b,n,l,t,m,rr,lr;
 6 int check(ll k)
 7 {
 8     ll f = a + (l - 1) * b,rrr = a + (k - 1) * b,su=((f+rrr)*(k-l+1))>>1;
 9     if(t*m<su || rrr > t)return 0;
10     else return 1;
11 }
12 int main()
13 {
14     cin>>a>>b>>n;
15     for(int i=1;i<=n;i++)
16     {
17         cin>>l>>t>>m;
18         if(a+b*(l-1) > t)
19         {
20             puts("-1");
21             continue;
22         }
23         lr = l;
24         rr = l + t+10;
25         while(lr<rr)
26         {
27             int mid = (lr + rr+ 1) >> 1;
28             if(check(mid))lr=mid;else rr=mid-1;
29         }
30         cout<<lr<<endl;
31     }
32     return 0;
33 }

CF 533B. Work Group

题目大意:给出一棵有根树,每个点都有点权,从中选出一些点,使得每个选中的点的子树中都有偶数个选中点,求选出点最大的点权
思路:很明显的树dp,显然选中当前点的话,那它的子数选中的点只能选择偶数,如果不选当前的点,子树可以选偶数或奇数个点,那接下来问题就转化成了对于一个点,它的子树可以选奇数个点或偶数的点,以及一个权值,如何选才能使权值最大并且点数为奇数/偶数。这个显然是一个一维的DP,于是问题得到解决
唔,细节处理还是很重要的,由于一开始什么0个点都没选的时候点数是偶数,因此需要一开始将奇数转移的地方封印起来,直到选了奇数个后才能用odd转移

 1 #include<cstdio>
 2 #include<iostream>
 3 #include<cstring>
 4 #define maxn 400000
 5 using namespace std;
 6 long long now=0,head[maxn],next[maxn],point[maxn],p[maxn];
 7 long long dp[400000][3],root;
 8 void add(int x,int y)
 9 {
10     next[++now]=head[x];
11     head[x]=now;
12     point[now]=y;
13 }
14 long long dfs(long long k,long long par)
15 {
16     if(dp[k][par]!=-1)return dp[k][par];
17     long long even = 0 ,odd = -1;
18     for(int i=head[k];i;i=next[i])
19     {
20         long long pp = point[i],u=dfs(pp,0) , v = dfs(pp,1);
21         long long tempe = even , tempo = odd;
22         even += u;odd += u;
23         if(v != -1)
24         {
25             if(tempo != -1)even = max(even , tempo + v);
26             odd = max(odd , tempe +v);
27         }
28     }
29     dp[k][0]=even;
30     dp[k][1] = max(even + p[k], odd);
31     return dp[k][par];
32 }
33 int main()
34 {
35     long long n,x;
36     memset(dp,-1,sizeof(dp));
37     cin>>n;
38     for(int i=1;i<=n;i++)
39     {
40         cin>>x>>p[i];
41         if(x==-1)root=i;
42         else
43         {
44             add(x,i);
45         }
46     }
47     cout<<max(dfs(root,0),dfs(root,1))<<endl;
48     return 0;
49 }

GCJ 2015 A. Counter Culture

题目大意:给你一个数,从0出发每次可以对这个数进行两个操作:1.将这个数反转:也就是1234变成4321 2.将这个数加一

问从0出发最少多少次操作能变成这个数

思路:这题做的,快苦了。。。首先20一下只能一步一步加,以上呢?先凑出来到这个位数至少需要多少步,比如到达100需要多少步,1000需要多少步,然后将末尾一半的数凑成高位,反转,再将后一半的数凑成高位就能过大数据了,可惜的是闹抽两句话写反了结果fst!!!!

 1 #include<iostream>
 2 #include<fstream>
 3 #include<cstring>
 4 #include<algorithm>
 5 #define maxn 500
 6 using namespace std;
 7 ifstream fin("a.in");
 8 ofstream fout("a.out");
 9 //#define fin cin
10 //#define fout cout
11 int deg[100]={0,1,10,29,138,337,1436,3435,14434,34433,144432,344431,1444430,3444429,14444428};
12 int main()
13 {
14     long long t,n,cas=0;
15     fin>>t;
16     while(t--)
17     {
18         long long ans=0;
19         fin>>n;
20         int flag=0;
21         if(n<=20)
22         {
23             fout<<"Case #"<<++cas<<": "<<n<<endl;
24         }
25         else
26         {
27             long long temp=n;
28             if(n%10==0)
29             {
30                 n--;
31                 flag=1;
32             }
33             int a[100],h=0;
34             while(n)
35             {
36                 a[++h]=n%10;
37                 n/=10;
38             }
39             int u=h>>1;
40             ans += deg[h];
41             long long v=0;
42             for(int i=h-u+1;i<=h;i++)
43             {
44                 v = v * 10 + a[i];
45             }
46             ans  += v;
47             v=0;
48             for(int i=h-u;i>=1;i--)
49             {
50                 v= v*10 +a[i];
51             }
52             ans+=v;
53             v=1;
54             for(int i=1;i<h;i++)v*=10;
55             if(flag)ans++;
56             fout<<"Case #"<<++cas<<": "<<min(ans,temp-v+deg[h])<<endl;
57         }
58     }
59     return 0;
60 }

Codeforces Round #300 B. Quasi Binary

题目大意:给出一个数(0到1e6),问你它能是最少多少quasibinary的和,一个十进制数是quasibinary当且仅当它十进制数位上只有0和1

思路:显然这个范围内quasibinary不多,先预处理出来,然后就是一个裸到不行的DP,记录路径就可以

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 #define maxn 2000000
 6 using namespace std;
 7 int a[maxn],h=0,ini[maxn],dp[maxn],last[maxn],ans[maxn];
 8 void add(int temp[])
 9 {
10     int sum=0;
11     for(int i=1;i<=7;i++)sum = sum*10 + temp[i];
12     ini[++h]=sum;
13 }
14 void dfs(int k)
15 {
16     if(k>7){add(a);return ;}
17     a[k]=1;dfs(k+1);
18     a[k]=0;dfs(k+1);
19 }
20 int dfs2(int k)
21 {
22     if(dp[k]!=-1)return dp[k];
23     int ret=0x3f3f3f3f;
24     for(int i=1;i<=h;i++)
25     {
26         if(k-ini[i]>=0)
27         {
28             int u=dfs2(k-ini[i]);
29             if(u < ret)
30             {
31                 ret = u;
32                 last[k] = i;
33             }
34         }
35         else break;
36     }
37     return dp[k]=ret+1;
38 }
39 int main()
40 {
41     int n;
42     scanf("%d",&n);
43     dfs(1);
44     memset(dp,-1,sizeof(dp));
45     dp[0]=0;
46     h--;
47     sort(ini+1,ini+1+h);
48     printf("%d\n",dfs2(n));
49     int v=0;
50     while(last[n]!=0)
51     {
52         ans[++v]=ini[last[n]];
53         n-=ini[last[n]];
54     }
55     sort(ans+1,ans+1+v);
56     for(int i=1;i<=v;i++)printf("%d ",ans[i]);
57     return 0;
58 }

时间: 2024-07-31 10:22:06

屯题大法好的相关文章

屯题 - -。

2015-09-12 21:59:09 最近屯题: 1:319 div1 D 分段矩阵快速幂 + floyd 2:319 div2 B 鸽巢原理 3:ZOJ 9月月赛 H题 NTT 4:ZOJ 9月月赛 K题 容斥 5:ZOJ 9月月赛 G题 负坐标积分出问题?

屯题计划

感觉lxt一天到晚就是在浪啊浪, 毫无斗志, 颓废得不得了, 每天看小说玩手机到三四点然后整个人都是乱七八糟的. 不行不行我要振作起来了! 从最开始学语言到现在都快两年过去了 T T , 代码能力还是渣成这样简直不能看 T T 觉得应该学学zj爷们屯题. 加油! (题目是直接从劼很久以前的几篇屯题计划里边搬过来的我之前做过的题就删掉了 [BZOJ1822][JSOI2010]Frozen Nova 冷冻波 很水的网络流加计算几何, 然而计算几何部分非常莫名奇妙, 题目应该是判断一个圆是否与一个线

屯题... 8.3

2015-08-03 00:12:31 ... SCOI 1293 - 1298 ... CDQ 分治论文.例题

[屯题] DP系列

P1222P1009P1037P1207P2326P1677P1669P1642P1679P1233P1668P1898P1806P1492P1801P1592P1537P2442P2201P1649P1633P1643P3688P3704P1046P1584P1710P2101P1672P1664P2023P3297P1025P2364P1044P2091P1023P1093P3437P3427P1089P2708P3791P1487P3770P3769P2298P1049P3036P1485

屯题1

1.UOJ118  赴京赶考 考虑a[i]!=a[i+1],那么无论哪一行,这两个相邻的走过去都需要1的代价 同样的b[i]!=b[i+1],那么无论哪一列,这两个相邻的走过去都需要1的代价 所以(x,y)走到(xx,yy)等价于x走到xx的最小代价(1维情况即可) +y走到yy的最小代价(也是1维情况) 维护一个前缀和就好了 代码如下 #include<bits/stdc++.h> #define N 500005 using namespace std; int n,m,Q,xc,xs,y

【搭楼】做题记录

以后做了题还是在这里写一下,觉得好的再去发题解(感觉无脑发题解意义不大) 也不一定是做了的题,看了没打但觉得不错的也可以发上来 (5.23-5.24 第三次月考被X得相当爽) 5.23 星期六 [贪心]Bzoj4027 HEOI2014 兔子与樱花 要是父亲合并儿子又合并就混乱了.然后发现,反正贡献都是一?能合并就在儿子处合并?贪心. [分块]Bzoj3343 教主的魔法 做之前知道了tag,于是很快就想到了算法.还没打过分块呢,于是先去膜拜了一下别人的代码.自己打出来后各种WA,太晚了没调出来

【POJ 1151】Atlantis

离散化后扫描线扫一遍. 夏令营时gty学长就讲过扫描线,可惜当时too naive,知道现在才写出模板题. 当时也不会线段树啊233 #include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int N = 103; struct node { double x1, x2, y; int d; node (double _x1 = 0, double _x2 = 0

BZOJ一天提交 51纪念(二)

今天作死又交了一发呢...于是屯题就全用完啦~ 有一次拷错CE,还有一次本来的程序就是错的的说... 可是我希望看到我努力的人并不会看到我的努力呢,尽管如此一个人也要坚持走到底哦,就如同这不完美的提交一样呢.但是49 = 72才是最好看的哟!

1640: [Usaco2007 Nov]Best Cow Line 队列变换|后缀数组|贪心

做完1692发现还有弱化版本1640 打板子刷水题大法好,骗访问量大法好 #include<algorithm> #include<iostream> #include<cstdlib> #include<cstring> #include<vector> #include<cstdio> #include<queue> #include<cmath> #include<set> #include&