由于本Cho太过懒惰,不再更新之前已经AC以及个人认为没有很大必要写的题目;
请善用 Ctrl + F qwq
排名先后仅看做题顺序
#1.1 1085 背包问题
01背包模板
1 #include<cstdio>
2 #include<iostream>
3 using namespace std;
4
5 int n,maxx,DP[1000000],w,v;
6
7 int main(){
8 scanf("%d%d",&n,&maxx);
9
10 for(int i = 1;i <= n;i++){
11 scanf("%d%d",&w,&v);
12 for(int j = maxx;j >= w;j--)
13 DP[j] = max(DP[j],DP[j-w]+v);
14 }
15
16 cout << DP[maxx];
17
18 return 0;
19 }
#1.2 1086 背包问题 V2
多重背包 + 二进制优化
什么是二进制优化呢?当前物品有数量 c ,将其拆分成 1 2 4 8 16 ... (剩下) ,然后一个个做01背包
决策每一个数字的时候 (1,2,4...) ,选与不选,相当于该物品已有数量加不加当前数字,而我们将决策 c 的二进制表示的每一位,那么所有的 1,2,4,... 是可以组合表示出 ≤c 的所有数量的状态的
这样就优化成一层 log
1 #include<cstdio>
2 #include<iostream>
3 using namespace std;
4
5 int n,maxx,DP[1000000],w,v,c;
6
7 int main(){
8 scanf("%d%d",&n,&maxx);
9
10 for(int i = 1;i <= n;i++){
11 scanf("%d%d%d",&w,&v,&c);
12 int d = 1;
13 while(d <= c){
14 for(int j = maxx;j >= d*w;j--)
15 DP[j] = max(DP[j],DP[j-d*w]+d*v);
16 c -= d;
17 d *= 2;
18 }for(int j = maxx;c && j >= c*w;j--)
19 DP[j] = max(DP[j],DP[j-c*w]+c*v);
20 }
21
22 cout << DP[maxx];
23
24 return 0;
25 }
#1.3 1257 背包问题 V3
跟分数规划打了场遭遇战= =
数学分析目标式,二分答案
此处解题报告 [51nod] 1257 背包问题 V3
1 #include<stdio.h>
2 #include<math.h>
3 #include<iostream>
4 #include<algorithm>
5 using namespace std;
6
7 int n,k;
8 long long ansv,answ;
9
10 double eps = 0.000000001;
11
12 struct data{
13 long long w,v;
14 double vrw;
15 }arr[1000000];
16
17 bool cmp(const data &a,const data &b){ return a.vrw > b.vrw; }
18
19 bool check(long long &sumv,long long &sumw,double line){
20 for(int i = 1;i <= n;i++)
21 arr[i].vrw = 1.0*arr[i].v-line*arr[i].w;
22
23 sort(arr+1,arr+1+n,cmp);
24
25 double tmp = 0;
26 sumv = 0,sumw = 0;
27 for(int i = 1;i <= k;i++)
28 sumv += arr[i].v,
29 sumw += arr[i].w,
30 tmp += arr[i].vrw;
31
32 return tmp >= 0;
33 }
34
35 long long gcd(long long a,long long b){
36 if(a < b) swap(a,b);
37 return !b?a:gcd(b,a%b);
38 }
39
40 int main(){
41
42 scanf("%d%d",&n,&k);
43
44 for(int i = 1;i <= n;i++)
45 scanf("%lld%lld",&arr[i].w,&arr[i].v);
46
47 double L = 0,R = 1000000;
48 long long sumv,sumw;
49 while(R-L > eps){
50 // printf("%.8lf %.8lf\n",L,R);
51 double mid = (L+R)/2;
52 if(check(sumv,sumw,mid)) ansv = sumv, answ = sumw, L = mid;
53 else R = mid;
54 }
55
56 long long d = gcd(ansv,answ);
57 printf("%lld/%lld",ansv/d,answ/d);
58
59 return 0;
60 }
#2.1 1136 欧拉函数
Emmmm,现在有 m 与 p 互质且 p 为质数,那么 phi( p ) = p-1 ,phi( mp ) = phi( m )*phi( p ) = phi( m )*( p-1 )
然后对于 phi( mpp ) = phi( mp )*p
Emmmm 这个我居然没法证明
我们知道如果 phi( mpp ) = phi ( mp )* ??? ,那么 ??? = phi( mpp ) / phi( mp )
而 mpp 和 mp 的质因子是一样的
所以根据公式 phi ( x ) = x*(1-.........) 我们知道对于 x 后面的部分,phi ( mpp ) 和 phi ( mp )是相同的,那么两元相除得 phi ( mpp ) / phi ( mp ) = p
1 #include<stdio.h>
2 #include<iostream>
3 using namespace std;
4
5 //int prime[100000],primesize;
6 //bool isprime[100000];
7 //void getlist(int listsize){
8 // listsize = (int)sqrt(listsize)+10;
9 // isprime[
10 //}
11
12 int phi(int &x){
13 int ans = 1;
14 for(int i = 2;i*i <= x;i++){
15 if(x%i) continue;
16 ans *= (i-1);
17 x /= i;
18 while(x%i == 0){
19 ans *= i;
20 x /= i;
21 }
22 }if(x > 1) ans *= x-1; // 这条和 i*i <= x 可以防止x为大质数导致TLE
23 return ans;
24 }
25
26 int main(){
27 int n;
28 scanf("%d",&n);
29
30 cout << phi(n);
31
32 return 0;
33 }
#3.1 1242 斐波那契数列的第N项
矩阵快速幂
1 #include<cstdio>
2 #include<iostream>
3 #define mod 1000000009
4 using namespace std;
5
6 struct MAT{
7 long long d[5][5];
8 MAT(){ d[1][1] = d[1][2] = d[2][1] = d[2][2] = 0; }
9 void Init(){
10 d[1][2] = d[2][1] = d[2][2] = 1;
11 d[1][1] = 0;
12 }
13 }I;
14
15 MAT mul(MAT A,MAT B){
16 MAT C;
17 for(int i = 1;i <= 2;i++)
18 for(int j = 1;j <= 2;j++)
19 for(int k = 1;k <= 2;k++)
20 C.d[i][j] = (C.d[i][j]+A.d[i][k]*B.d[k][j]%mod)%mod;
21 return C;
22 }
23
24 MAT ksm(MAT A,long long k){
25 MAT B = A;
26 k--;
27 while(k){
28 if(k&1) B = mul(B,A);
29 A = mul(A,A);
30 k >>= 1;
31 }return B;
32 }
33
34 int main(){
35 long long n;
36 scanf("%lld",&n);
37
38 if(n <= 2) return printf("1"),0;
39
40 MAT I;
41 I.Init();
42
43 I = ksm(I,n-1);
44
45 long long c = (I.d[1][1]+I.d[1][2])%mod;
46
47 cout << c;
48
49 return 0;
50 }
#4 1106 质数检测
Miller-Rabbin 素性测试,二次探测才是核心
1 #include<stdio.h> 2 #include<iostream> 3 #define LL long long 4 using namespace std; 5 6 int prime[8] = {2,3,5,7,11,13,17,19}; 7 8 LL ksm(LL x,LL k,LL m){ 9 if(k == 1) return x%m; 10 if(!k) return 1; 11 LL b = 1; 12 while(k){ 13 if(k&1) b = b*x%m; 14 x = x*x%m; 15 k >>= 1; 16 }return b%m; 17 } 18 19 bool TD(LL x,LL a){ 20 if(x == a) return true; 21 LL m = x-1; 22 while(m % 2 == 0) m >>= 1; 23 LL t = ksm(a,m,x); 24 while(m != x-1 && t != 1 && t != x-1) 25 t = t*t%x,m <<= 1; 26 return (m&1 || t == x-1); 27 } 28 29 bool isPrime(LL x){ 30 if(x == 2) return true; 31 if(x < 1 || x % 2 == 0) return false; 32 for(int i = 0;i < 8;i++) 33 if(!TD(x,prime[i])) return false; 34 return true; 35 } 36 37 int main(){ 38 int n; 39 scanf("%d",&n); 40 41 for(int i = 1;i <= n;i++){ 42 long long x; scanf("%lld",&x); 43 if(isPrime(x)) printf("Yes\n"); 44 else printf("No\n"); 45 } 46 47 return 0; 48 }