├── [提高训练]图论之最短路径 ├── phoneline.cpp └── trip.cpp ├── old ├── lcs.cpp ├── nbag.cpp ├── 01bag.cpp ├── budget.cpp ├── dance.cpp ├── flower.cpp ├── bashuma.cpp ├── equation.cpp ├── equation1.cpp ├── 动态规划(一).pptx ├── 动态规划(二).pptx ├── noip2017 │ ├── chess.cpp │ ├── math.cpp │ ├── pack.cpp │ ├── cheese.cpp │ ├── complexity.cpp │ └── treasure.cpp ├── noip2018 │ ├── load.cpp │ ├── travel.cpp │ ├── money.cpp │ └── track.cpp ├── 信息学奥赛(NOIP)复赛学习方法推荐.docx ├── sandmerge.cpp └── sihuanghou.cpp ├── [基本算法]递推 ├── flag.png ├── cover.md ├── flag.cpp ├── cover.cpp ├── flag.md ├── marathon.md └── marathon.cpp ├── [c++基础]一维数组的统计查找和排序 ├── count.exe ├── height2.md ├── paiming.md ├── count.cpp ├── count.md ├── paiming.cpp ├── paiming1.cpp └── height2.cpp ├── [c++基础]函数的递归调用和应用举例 ├── tower.exe ├── tower.cpp ├── ratf.cpp ├── number.cpp └── twopower.cpp ├── [csp-jx2019] ├── P5689多叉堆.cpp ├── P5690日期.cpp ├── P5686和积和.cpp └── P5687网格图.cpp ├── [基本算法]分治和递归 ├── car.md └── car.cpp ├── [基本算法]穷举 ├── triangle.cpp ├── coin.cpp ├── ratio.cpp ├── comb1.cpp ├── comb.cpp ├── cow.cpp └── matches.cpp ├── [基本算法]阶段测试一 ├── count.cpp ├── set.md ├── set.cpp ├── bishop.cpp └── whatbase.cpp ├── [洛谷2020十一月月赛] ├── P7106.cpp ├── P7108.cpp └── P7101.cpp ├── [基本算法]贪心 ├── delete.cpp ├── kaj.md ├── kaj.cpp ├── max.cpp ├── water.cpp ├── match.cpp └── pebble.cpp ├── [基本算法]宽度优先搜索 ├── area.md └── area.cpp ├── [洛谷题单]动态规划之动态规划的引入 ├── P1216.cpp └── P1434.cpp ├── [洛谷题单]动态规划之线性状态动态规划 ├── P1439.cpp ├── p1439_1.cpp ├── P1020_1.cpp ├── P5858.cpp ├── P1280.cpp ├── P1020.cpp ├── p4933_1.cpp ├── P5858_1.cpp └── P4933.cpp ├── [基本算法]动态规划 ├── lcs.cpp ├── flower.cpp ├── digtriangle.cpp ├── missile1.cpp ├── book.cpp ├── chorus.cpp ├── missile.cpp └── getnum.cpp ├── [基本算法]深度优先搜索 ├── volume.cpp ├── decompose.cpp ├── ticket.cpp └── meeting.cpp ├── [c++基础]二维数组的定义操作和数字方阵 ├── carpet.cpp ├── magic.cpp ├── square2.cpp └── snake2.cpp ├── [CSP-S2019] ├── P5665-划分.cpp ├── P5657-格雷码.cpp ├── P5658-括号树.cpp ├── P5664-Emiya.cpp └── P5666-树的重心.cpp ├── [洛谷题单]线段树与树状数组 ├── P3373.cpp └── P3372.cpp ├── [洛谷题单]动态规划之区间与环形动态规划 ├── CF607B.cpp ├── P4170.cpp └── P1220.cpp ├── [c++基础]指针与链表 ├── monkey.cpp └── flag.cpp ├── [基本算法]回溯法 ├── book.cpp └── mas.cpp ├── [洛谷2020十月月赛] ├── P6858_1.cpp └── P6858.cpp ├── [提高训练]动态规划之树型DP ├── choose.cpp ├── strategi.cpp ├── aniv.cpp ├── TREE.cpp ├── transfer.cpp ├── apple.cpp ├── leaf.cpp ├── guard.cpp ├── apple1.cpp ├── knight.cpp └── travel.cpp ├── [提高训练]动态规划之区间DP ├── energy.cpp ├── kh.cpp ├── separation.cpp └── merge.cpp ├── [洛谷题单]二叉堆与ST表 ├── P3865.cpp ├── P1631.cpp ├── P1168.cpp ├── P4053.cpp └── P1801.cpp ├── [基本数据结构]栈及栈的应用 ├── expr.cpp └── expr_common.cpp ├── [洛谷题单]动态规划之树与图上的动态规划 ├── P1613.cpp ├── P1273.cpp └── P2585.cpp ├── [洛谷题库] ├── p2052.cpp ├── P5888.cpp ├── P2886.cpp ├── P1642.cpp └── P1283.cpp ├── [提高训练]动态规划之数位DP ├── test.cpp ├── none62.cpp ├── test2.cpp ├── windy.cpp ├── data.cpp └── count.cpp ├── [洛谷题单]搜索剪枝策略 ├── P4799.cpp ├── P3067.cpp └── P5507.cpp ├── [洛谷题单]动态规划之状态压缩动态规划 ├── P1879.cpp └── P1896.cpp ├── [洛谷题单]图论之最短路径 ├── P1119.cpp ├── P4779.cpp ├── P1629.cpp ├── P1462.cpp └── P1522.cpp ├── [基本数据结构]并查集及其应用 └── relation.cpp ├── [c++基础]结构体的定义和应用 ├── birthday.cpp └── set.cpp ├── [洛谷题单]图论之基础树上问题 ├── P3379.cpp ├── P1395.cpp ├── P3398.cpp ├── P4281.cpp ├── P5836.cpp └── P3629.cpp ├── [提高训练]动态规划之状压DP ├── zoo.cpp ├── cowfood.cpp ├── horse.cpp ├── paint.cpp └── cannon.cpp ├── [洛谷提高历练地] └── [搜索] │ ├── P1120-小木棍.cpp │ ├── P1441-fama.cpp │ └── P1378-油滴扩展.cpp ├── [CSP-S2020] ├── P7075.cpp └── P7076.cpp ├── [提高训练]图论之生成树 ├── dark_castle.cpp ├── tree.cpp ├── newstart.cpp ├── network.cpp └── award.cpp ├── [洛谷题单]图论之连通性问题 ├── P2746.cpp ├── P3387.cpp └── P2341.cpp └── [提高训练]动态规划之单调队列优化 └── trade.cpp /[提高训练]图论之最短路径/phoneline.cpp: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /old/lcs.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenghuasheng/NOIP/HEAD/old/lcs.cpp -------------------------------------------------------------------------------- /old/nbag.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenghuasheng/NOIP/HEAD/old/nbag.cpp -------------------------------------------------------------------------------- /old/01bag.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenghuasheng/NOIP/HEAD/old/01bag.cpp -------------------------------------------------------------------------------- /old/budget.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenghuasheng/NOIP/HEAD/old/budget.cpp -------------------------------------------------------------------------------- /old/dance.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenghuasheng/NOIP/HEAD/old/dance.cpp -------------------------------------------------------------------------------- /old/flower.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenghuasheng/NOIP/HEAD/old/flower.cpp -------------------------------------------------------------------------------- /[基本算法]递推/flag.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenghuasheng/NOIP/HEAD/[基本算法]递推/flag.png -------------------------------------------------------------------------------- /old/bashuma.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenghuasheng/NOIP/HEAD/old/bashuma.cpp -------------------------------------------------------------------------------- /old/equation.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenghuasheng/NOIP/HEAD/old/equation.cpp -------------------------------------------------------------------------------- /old/equation1.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenghuasheng/NOIP/HEAD/old/equation1.cpp -------------------------------------------------------------------------------- /old/动态规划(一).pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenghuasheng/NOIP/HEAD/old/动态规划(一).pptx -------------------------------------------------------------------------------- /old/动态规划(二).pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenghuasheng/NOIP/HEAD/old/动态规划(二).pptx -------------------------------------------------------------------------------- /old/noip2017/chess.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenghuasheng/NOIP/HEAD/old/noip2017/chess.cpp -------------------------------------------------------------------------------- /old/noip2017/math.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenghuasheng/NOIP/HEAD/old/noip2017/math.cpp -------------------------------------------------------------------------------- /old/noip2017/pack.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenghuasheng/NOIP/HEAD/old/noip2017/pack.cpp -------------------------------------------------------------------------------- /old/noip2018/load.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenghuasheng/NOIP/HEAD/old/noip2018/load.cpp -------------------------------------------------------------------------------- /old/noip2017/cheese.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenghuasheng/NOIP/HEAD/old/noip2017/cheese.cpp -------------------------------------------------------------------------------- /old/noip2018/travel.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenghuasheng/NOIP/HEAD/old/noip2018/travel.cpp -------------------------------------------------------------------------------- /old/noip2017/complexity.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenghuasheng/NOIP/HEAD/old/noip2017/complexity.cpp -------------------------------------------------------------------------------- /old/noip2017/treasure.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenghuasheng/NOIP/HEAD/old/noip2017/treasure.cpp -------------------------------------------------------------------------------- /[c++基础]一维数组的统计查找和排序/count.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenghuasheng/NOIP/HEAD/[c++基础]一维数组的统计查找和排序/count.exe -------------------------------------------------------------------------------- /[c++基础]函数的递归调用和应用举例/tower.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenghuasheng/NOIP/HEAD/[c++基础]函数的递归调用和应用举例/tower.exe -------------------------------------------------------------------------------- /old/信息学奥赛(NOIP)复赛学习方法推荐.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenghuasheng/NOIP/HEAD/old/信息学奥赛(NOIP)复赛学习方法推荐.docx -------------------------------------------------------------------------------- /[基本算法]递推/cover.md: -------------------------------------------------------------------------------- 1 | # 铺瓷砖 2 | ## 题目描述 3 | 用红色的 1×1 和黑色的 2×2 两种规格的瓷砖不重叠地铺满 n×3 的路面,求出有多少种不同的铺设方案。 4 | ## 输入格式 5 | 一行一个整数 n,0 2 12 | 13 | ### 输出样例 14 | > 3 15 | 16 | ## 数据范围与提示 -------------------------------------------------------------------------------- /[csp-jx2019]/P5689多叉堆.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using namespace std; 4 | const int MAXN=300000; 5 | const int MAXQ=300000; 6 | int size[MAXN]; 7 | long long heapnum[MAXN]; 8 | vector tree; 9 | int n,q; 10 | long long c[MAXN+1]; 11 | int main(){ 12 | 13 | } -------------------------------------------------------------------------------- /[基本算法]递推/flag.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | ifstream fin("flag.in"); 4 | ofstream fout("flag.out"); 5 | const int MAXN=46; 6 | int s[MAXN]; 7 | int n; 8 | int main(){ 9 | fin>>n; 10 | s[1]=2; 11 | s[2]=2; 12 | for(int i=3;i<=n;i++) s[i]=s[i-1]+s[i-2]; 13 | fout<120 5 25 11 | 12 | ### 样例输出 13 | >9.60 14 | ## 数据范围与提示 15 | -------------------------------------------------------------------------------- /[基本算法]递推/cover.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | ifstream fin("cover.in"); 4 | ofstream fout("cover.out"); 5 | 6 | const int MAXN=1001; 7 | int s[MAXN]; 8 | int n; 9 | 10 | int main(){ 11 | fin>>n; 12 | s[0]=1; 13 | s[1]=1; 14 | for(int i=2;i<=n;i++) s[i]=(s[i-1]+s[i-2]*2) % 12345; 15 | fout< 2 | using namespace std; 3 | 4 | int n; 5 | 6 | void hanno(int n,char a ,char c,char b){ 7 | if (n==1){ 8 | cout<"<>n; 18 | hanno(n,'A','C','B'); 19 | } -------------------------------------------------------------------------------- /[c++基础]函数的递归调用和应用举例/ratf.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | int n,k; 5 | 6 | int fzs(int x){ 7 | if (x>n>>k; 18 | cout< 2 | using namespace std; 3 | 4 | int n; 5 | int yzh(int x){ 6 | int ret=0; 7 | for(int i=2;i<=x/2;i++){ 8 | if (x%i==0) ret+=i; 9 | } 10 | return ret; 11 | } 12 | int main(){ 13 | cin>>n; 14 | for(int a=2;a<=n;a++){ 15 | int b=yzh(a); 16 | if (b<=n&&yzh(b)==a) cout< 2 | using namespace std; 3 | 4 | ifstream fin("triangle.in"); 5 | ofstream fout("triangle.out"); 6 | 7 | int n; 8 | 9 | int main(){ 10 | fin>>n; 11 | long ans=0; 12 | for(int c=1;c<=n/2;c++){ 13 | for(int a=1;a<=c;a++){ 14 | int b=n-c-a; 15 | if (b>c||bc) ans++; 17 | } 18 | } 19 | fout< 2 | using namespace std; 3 | 4 | ifstream fin("count.in"); 5 | ofstream fout("count.out"); 6 | 7 | const int MAXN=1000; 8 | int s[MAXN+1]; 9 | int n; 10 | 11 | int solution(int k){ 12 | if (s[k]>0) return s[k]; 13 | int c=1; 14 | int mid=k/2; 15 | for(int i=1;i<=mid;i++) c+=solution(i); 16 | s[k]=c; 17 | return c; 18 | } 19 | 20 | int main(){ 21 | fin>>n; 22 | fout< 4 3 16 | 17 | ### 样例输出 18 | > 6 19 | ## 数据范围与提示 20 | -------------------------------------------------------------------------------- /[基本算法]递推/flag.md: -------------------------------------------------------------------------------- 1 | # 彩带 2 | ## 题目描述 3 | 一中 90 周年校庆,小林准备用一些白色、蓝色和红色的彩带来装饰学校超市的橱窗,他希望满足以下两个条件: 4 | (1) 相同颜色的彩带不能放在相邻的位置; 5 | (2) 一条蓝色的彩带必须放在一条白色的彩带和一条红色的彩带中间。 6 | 现在,他想知道满足要求的放置彩带的方案数有多少种。例如,如图 9.4-1 所示为橱窗宽度n=3 的所有放置方案,共 4 种。 7 | 8 | 9 | ## 输入格式 10 | 一行一个整数 n,表示橱窗宽度(或者说彩带数目)。 11 | ## 输出格式 12 | 一行一个整数,表示装饰橱窗的彩带放置方案数。 13 | ## 样例 14 | ### 样例输入 15 | > 3 16 | 17 | ### 样例输出 18 | > 4 19 | 20 | ## 数据范围与提示 21 | 对 30% 的数据满足:1≤n≤15。 22 | 对 100% 的数据满足:1≤n≤45。 -------------------------------------------------------------------------------- /[洛谷2020十一月月赛]/P7106.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using namespace std; 4 | 5 | string s,s1; 6 | char reverse[16]={'F','E','D','C','B','A','9','8','7','6','5' 7 | ,'4','3','2','1','0'}; 8 | 9 | int main(){ 10 | cin>>s; 11 | s1="#"; 12 | for(int i=1;i='0'&&c<='9') val=c-'0'; 16 | else val=c-'A'+10; 17 | s1+=reverse[val]; 18 | } 19 | cout< 2 | #include 3 | using namespace std; 4 | ifstream fin("delete.in"); 5 | ofstream fout("delete.out"); 6 | 7 | string num; 8 | int s; 9 | int main(){ 10 | fin>>num; 11 | fin>>s; 12 | int l=num.length(); 13 | if (s>=l) fout<<0; 14 | else { 15 | int i=0; 16 | for(int k=0;k 100 16 | 9 17 | 90 18 | 20 19 | 20 20 | 30 21 | 50 22 | 60 23 | 70 24 | 80 25 | 90 26 | 27 | ### 输出样例 28 | > 6 29 | ## 数据范围与提示 -------------------------------------------------------------------------------- /[基本算法]穷举/coin.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using namespace std; 4 | FILE *fpin,*fpout; 5 | 6 | long long n; 7 | 8 | int main(){ 9 | fpin=fopen("coin.in","r"); 10 | fpout=fopen("coin.out","w"); 11 | 12 | fscanf(fpin,"%lld",&n); 13 | while(n>0){ 14 | long long k=(-1+sqrt(1+8.0*n))/2; 15 | long long n_=(k+1)*k/2; 16 | long long ans=k*(k+1)*(2*k+1)/6; 17 | ans+=(k+1)*(n-n_); 18 | fprintf(fpout,"%lld\n",ans); 19 | fscanf(fpin,"%lld",&n); 20 | } 21 | } -------------------------------------------------------------------------------- /[基本算法]宽度优先搜索/area.md: -------------------------------------------------------------------------------- 1 | # 最大黑区域 2 | ## 题目描述 3 | 二值图像是由黑和白两种像素组成的矩形点阵,图像识别的一个操作是 求出图像中最大黑区域的面积。请设计一个程序完成二值图像的这个操 作。黑区域由黑像素组成,一个黑区域中的每像素至少与该区域中的另 一像素相邻,规定一个像素仅与其上、下、左、右的像素相邻。两个不 同的黑区域没有相邻的像素。一个黑区域的面积是其所包含的像素数。 4 | 5 | ## 输入格式 6 | 第 1 行含两个整数 n 和 m,1≤n、m≤100,分别表示二值图像的行数与 列数。后面n行,每行含m个整数0或1,其中第i行表示图像的第i行的m 个像素,0表示白像素,1 表示黑像素。每行中的两个数之间用一个空 格分隔。 7 | 8 | ## 输出格式 9 | 输出一行一个数,表示相应的图像中最大黑区域的面积。 10 | 11 | ## 样例 12 | ### 输入样例 13 | >5 6 14 | 0 1 1 0 0 1 15 | 1 1 0 1 0 1 16 | 0 1 0 0 1 0 17 | 0 0 0 1 1 1 18 | 1 0 1 1 1 0 19 | 20 | ### 输出样例 21 | >7 -------------------------------------------------------------------------------- /[c++基础]一维数组的统计查找和排序/height2.md: -------------------------------------------------------------------------------- 1 | # 美人松的高度2 2 | ## 题目描述 3 | 又到过年了,狗熊岭的动物们都忙碌起来,张灯结彩准备过年。李老板却要光头强砍掉一些百年美人松回去。美人松都是很高的,但是也不会超过长整型。现在光头强看到丛林里有 N 颗美人松按照从矮到高的顺序排好,当然每棵松的高度都是已知的。李老板要问光头强 M 次,每次询问高度为 K 的美人松有多少颗? 4 | ## 输入格式 5 | 第一行两个正整数 N 和 M,之间用一个空格隔开,1≤ N≤$10^6$,1≤M≤1000; 6 | 第二行 N 个正整数,之间用一个空格隔开,表示 N 棵美人松的高度; 7 | 第三行 M 个正整数 k,之间用一个空格隔开,表示 M 个询问,每次询问高度为 K 的美人松有多少棵,1≤k≤1000。 8 | ## 输出格式 9 | 一行 M 个整数,之间用一个空格隔开,分别表示对应每次询问高度为 K 的树的数量,如果没有,则输出 0 10 | 样例 11 | ### 输入样例 12 | > 5 2 13 | 2 3 3 4 5 14 | 3 4 15 | 16 | ### 输出样例 17 | > 2 1 18 | ## 数据范围与提示 19 | -------------------------------------------------------------------------------- /[基本算法]穷举/ratio.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | ifstream fin("ratio.in"); 5 | ofstream fout("ratio.out"); 6 | 7 | int A,B,L; 8 | int A_,B_; 9 | 10 | int main(){ 11 | fin>>A>>B>>L; 12 | A_=2*L;B_=1; 13 | for(int b=1;b<=L;b++){ 14 | for(int a=1;a<=L;a++){ 15 | if (a*B>=b*A){ 16 | if (a*B_ 5 13 | 300 5 14 | 200 6 15 | 350 4 16 | 400 6 17 | 250 5 18 | 19 | ### 输出样例 20 | > 0 21 | 0 22 | 1 23 | 1 24 | 3 25 | ## 数据范围与提示 -------------------------------------------------------------------------------- /[洛谷题单]动态规划之动态规划的引入/P1216.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | const int MAXR=1000; 4 | int r; 5 | int a[MAXR+1][MAXR+1]; 6 | int dp[MAXR+1][MAXR+1]; 7 | int ans; 8 | int main(){ 9 | cin>>r; 10 | for(int i=1;i<=r;i++) 11 | for(int j=1;j<=i;j++){ 12 | cin>>a[i][j]; 13 | } 14 | for(int i=1;i<=r;i++){ 15 | for(int j=1;j<=i;j++){ 16 | dp[i][j]=max(dp[i-1][j-1],dp[i-1][j])+a[i][j]; 17 | } 18 | } 19 | for(int j=1;j<=r;j++) ans=max(ans,dp[r][j]); 20 | cout< 2 | #include 3 | using namespace std; 4 | 5 | const int MAXN=200000; 6 | int num[MAXN]; 7 | int n; 8 | int main(){ 9 | //输入 10 | cin>>n; 11 | for(int i=0;i>num[i]; 12 | //从小到大排序 13 | sort(num,num+n); 14 | //统计个数并输出 15 | int prev=num[0]; 16 | int k=1; 17 | for(int i=1;i 2 | using namespace std; 3 | const int MAXN=10000; 4 | int n; 5 | int a[MAXN+1],b[MAXN+1]; 6 | int dp[MAXN+1][MAXN+1]; 7 | 8 | int main(){ 9 | cin>>n; 10 | for(int i=1;i<=n;i++) cin>>a[i]; 11 | for(int i=1;i<=n;i++) cin>>b[i]; 12 | 13 | for(int i=1;i<=n;i++) 14 | for(int j=1;j<=n;j++) { 15 | if (a[i]==b[j]) dp[i][j]=dp[i-1][j-1]+1; 16 | else { 17 | dp[i][j]=max(dp[i-1][j],dp[i][j-1]); 18 | } 19 | } 20 | cout< 2 | using namespace std; 3 | FILE *fpin,*fpout; 4 | 5 | const int MAXN=20; 6 | int n,r; 7 | int combs[MAXN]; 8 | 9 | void dfs(int x,int k){ 10 | combs[k-1]=x; 11 | if (k==r){ 12 | for(int i=0;i 2 | #include 3 | 4 | using namespace std; 5 | ifstream fin("lcs.in"); 6 | ofstream fout("lcs.out"); 7 | const int MAXL=5000; 8 | string s1,s2; 9 | int dp[MAXL+1][MAXL+1]; 10 | int l1,l2; 11 | 12 | int main(){ 13 | fin>>s1; 14 | fin>>s2; 15 | l1=s1.length(); 16 | l2=s2.length(); 17 | 18 | for(int i=1;i<=l1;i++) 19 | for(int j=1;j<=l2;j++){ 20 | if (s1[i-1]==s2[j-1]) dp[i][j]=dp[i-1][j-1]+1; 21 | else dp[i][j]=max(dp[i][j-1],dp[i-1][j]); 22 | } 23 | fout< 2 | using namespace std; 3 | ifstream fin("volume.in"); 4 | ofstream fout("volume.out"); 5 | 6 | const int MAXN=20; 7 | int v[MAXN]; 8 | int n,c; 9 | bool vflag[1001]; 10 | 11 | void dfs(int i,int sumv){ 12 | if (i>=n){ 13 | vflag[sumv]=true; 14 | }else { 15 | dfs(i+1,sumv); 16 | dfs(i+1,sumv+v[i]); 17 | } 18 | } 19 | int main(){ 20 | fin>>n; 21 | for(int i=0;i>v[i]; 23 | } 24 | dfs(0,0); 25 | c=0; 26 | for(int i=1;i<1001;i++) if (vflag[i]) c++; 27 | fout< 2 | using namespace std; 3 | const int MAXN=10000; 4 | int carpets[MAXN+1][4]; 5 | int n; 6 | int x,y; 7 | int main(){ 8 | cin>>n; 9 | for(int i=1;i<=n;i++){ 10 | for(int j=0;j<4;j++) cin>>carpets[i][j]; 11 | } 12 | cin>>x>>y; 13 | int find=-1; 14 | for(int i=n;i>0;i--){ 15 | if (x>=carpets[i][0]&&x<=carpets[i][0]+carpets[i][2]&& 16 | y>=carpets[i][1]&&y<=carpets[i][1]+carpets[i][3]){ 17 | find=i; 18 | break; 19 | } 20 | } 21 | cout< 2 | #include 3 | 4 | using namespace std; 5 | // ifstream fin("set.in"); 6 | // ofstream fout("set.out"); 7 | 8 | const int MAXN=30; 9 | int n,k; 10 | int s[MAXN+1][MAXN+1]; 11 | 12 | int main(){ 13 | cin>>n>>k; 14 | for(int i=1;i<=n;i++) s[i][1]=1; 15 | for(int i=2;i<=n;i++) 16 | for(int j=2;j<=i;j++){ 17 | s[i][j]=s[i-1][j-1]+j*s[i-1][j]; 18 | } 19 | for(int i=1;i<=n;i++){ 20 | for(int j=1;j<=k;j++) cout< 8 12 | 2 13 | 4 14 | 2 15 | 4 16 | 5 17 | 100 18 | 2 19 | 100 20 | 21 | ### 输出样例 22 | > 2 3 23 | 4 2 24 | 5 1 25 | 100 2 26 | ## 数据范围与提示 27 | 40%的数据满足:1<=n<=1000 28 | 80%的数据满足:1<=n<=50000 29 | 100%的数据满足:1<=n<=200000,每个数均不超过1500 000 000(1.5*10^9) -------------------------------------------------------------------------------- /[基本算法]分治和递归/car.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using namespace std; 4 | ifstream fin("car.in"); 5 | ofstream fout("car.out"); 6 | 7 | const float e=0.001; 8 | float s,a,b; 9 | 10 | 11 | int main(){ 12 | fin>>s>>a>>b; 13 | float left=0; 14 | float right=s/b; 15 | while(lefte) right=mid; 20 | else if (t1-t2>e) left=mid; 21 | else { 22 | fout< 2 | using namespace std; 3 | ifstream fin("flower.in"); 4 | ofstream fout("flower.out"); 5 | const int MAXN=100; 6 | int n,m; 7 | int a[MAXN+1]; 8 | int dp[MAXN+1][MAXN+1];//dp[i][j] 表示前i种花摆j盆的方案数 9 | 10 | int main(){ 11 | fin>>n>>m; 12 | for(int i=1;i<=n;i++) fin>>a[i]; 13 | 14 | for(int j=0;j<=m&&j<=a[1];j++) dp[1][j]=1; 15 | for(int i=2;i<=n;i++) 16 | for(int j=0;j<=m;j++) 17 | for(int k=0;k<=j&&k<=a[i];k++){ 18 | dp[i][j]+=dp[i-1][j-k]; 19 | dp[i][j]=dp[i][j] % 1000007; 20 | } 21 | 22 | fout< 4 13 | 0 0 14 | 8 3 15 | 11 -1 16 | 10 0 17 | 18 | ### 输出样例 19 | > 14 20 | 21 | ### 样例说明 22 | 跳过 2 号城市。 23 | ## 数据范围与提示 24 | 对于 40% 的数据满足:n≤1000。 25 | 对于 100% 的数据满足:3≤n≤100000,-1000≤x i ,y i ≤1000。 -------------------------------------------------------------------------------- /[c++基础]函数的递归调用和应用举例/twopower.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | int mi2[16]; 5 | int n; 6 | 7 | void express(int x){ 8 | for(int k=15;k>=0;k--){ 9 | if (x>=mi2[k]){ 10 | if (k==1) cout<<'2'; 11 | else if (k==0) cout<<"2(0)"; 12 | else { 13 | cout<<"2("; 14 | express(k); 15 | cout<<')'; 16 | } 17 | x=x-mi2[k]; 18 | if (x>0) cout<<'+'; 19 | else break; 20 | } 21 | } 22 | } 23 | int main(){ 24 | mi2[0]=1; 25 | for(int k=1;k<=15;k++) mi2[k]= mi2[k-1]*2; 26 | cin>>n; 27 | express(n); 28 | } -------------------------------------------------------------------------------- /[基本算法]深度优先搜索/decompose.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | ifstream fin("decompose.in"); 4 | ofstream fout("decompose.out"); 5 | 6 | int s[21]; 7 | int n; 8 | int count; 9 | 10 | void dfs (int dep,int k,int r){ 11 | for(int i=k;i<=r;i++){ 12 | s[dep]=i; 13 | int r1=r-i; 14 | if (r1==0) { 15 | for(int j=0;j<=dep;j++){ 16 | if (j>0) fout<<'+'<>n; 26 | dfs(0,1,n); 27 | fout<<"total="< 2 | using namespace std; 3 | const int MAXN=500000; 4 | int n,type; 5 | int a[MAXN+1]; 6 | unsigned long long dp[MAXN+1],last[MAXN+1]; 7 | unsigned long long sum[MAXN+1]; 8 | 9 | int main(){ 10 | cin>>n>>type; 11 | for(int i=1;i<=n;i++) cin>>a[i]; 12 | sum[0]=0; 13 | for(int i=1;i<=n;i++) sum[i]=sum[i-1]+a[i]; 14 | 15 | dp[0]=0; 16 | last[0]=0; 17 | for(int i=1;i<=n;i++){ 18 | for(int j=i;j>=1;j--){ 19 | if (sum[i]-sum[j-1]>=last[j-1]) { 20 | dp[i]=dp[j-1]+(sum[i]-sum[j-1])*(sum[i]-sum[j-1]); 21 | last[i]=sum[i]-sum[j-1]; 22 | break; 23 | } 24 | } 25 | } 26 | cout< 2 | #include 3 | #include 4 | #include 5 | using namespace std; 6 | ifstream fin("money.in"); 7 | ofstream fout("money.out"); 8 | int T; 9 | int n; 10 | int a[100]; 11 | bool flag[25001]; 12 | int main(){ 13 | fin>>T; 14 | for(int i=0;i>n; 16 | for(int j=0;j>a[j]; 17 | sort(a,a+n); 18 | memset(flag,false,sizeof(flag)); 19 | int max=a[n-1]; 20 | flag[0]=true; 21 | int m=0; 22 | for(int j=0;j 2 | using namespace std; 3 | ifstream fin("digtriangle.in"); 4 | ofstream fout("digtriangle.out"); 5 | 6 | const int MAXN=100; 7 | int n; 8 | int number[MAXN][MAXN]; 9 | int dp[MAXN][MAXN]; 10 | int ans; 11 | 12 | int main(){ 13 | fin>>n; 14 | for(int i=0;i>number[i][j]; 16 | dp[0][0]=number[0][0]; 17 | for(int i=1;ians) ans=dp[n-1][j]; 25 | fout< 2 | #include 3 | using namespace std; 4 | ifstream fin("sandmerge.in"); 5 | ofstream fout("sandmerge.out"); 6 | 7 | int N; 8 | int v[301]; 9 | int dp[301][301]; 10 | int vs[301][301]; 11 | 12 | int main(){ 13 | fin>>N; 14 | for(int i=1;i<=N;i++) fin>>v[i]; 15 | 16 | for(int i=1;i<=N;i++) 17 | for(int j=i;j<=N;j++) vs[i][j]=vs[i][j-1]+v[j]; 18 | 19 | for(int k=1;kN) break; 23 | dp[i][j]=dp[i][i]+dp[i+1][j]+vs[i][i]+vs[i+1][j]; 24 | for(int m=i+1;m 2 | using namespace std; 3 | int pos[4]; 4 | int ans=0; 5 | bool confict(int i,int j){ 6 | for(int k=0;k=4) { 20 | ans++; 21 | return; 22 | } 23 | for(int j=start;j<16;j++){ 24 | if (confict(i,j)) continue; 25 | pos[i]=j; 26 | dfs(i+1,j+1); 27 | } 28 | } 29 | int main(){ 30 | ans=0; 31 | dfs(0,0); 32 | cout< 2 | #include 3 | using namespace std; 4 | 5 | struct student{ 6 | int score,grade; 7 | }; 8 | bool compare(student a, student b) { 9 | if (a.score>b.score) return true; 10 | else if (a.score==b.score&&a.grade>n; 20 | for(int i=0;i>stus[i].score>>stus[i].grade; 22 | } 23 | sort(stus,stus+n,compare); 24 | for(int i=0;i 2 | #include 3 | using namespace std; 4 | const int MAXN=100000; 5 | int n,m,p; 6 | int a[MAXN+1]; 7 | struct Tag{ 8 | char op; 9 | int num; 10 | }; 11 | struct Node{ 12 | int l,r; 13 | int sum; 14 | vector lazy_tags; 15 | }; 16 | Node tree[(MAXN+1)*2]; 17 | void build(int i,int l,int r){ 18 | tree[i].l=l; 19 | tree[i].r=r; 20 | if (l==r) { 21 | tree[i].sum=a[l]; 22 | return; 23 | } 24 | int mid=(l+r)/2; 25 | build(i*2,l,mid); 26 | build(i*2+1,mid+1,r); 27 | 28 | } 29 | int main(){ 30 | cin>>n>>m>>p; 31 | for(int i=1;i<=n;i++) cin>>a[i]; 32 | 33 | } -------------------------------------------------------------------------------- /[c++基础]二维数组的定义操作和数字方阵/magic.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using namespace std; 4 | const int MAXN=20; 5 | 6 | int fz[MAXN][MAXN]; 7 | int n; 8 | int main(){ 9 | cin>>n; 10 | int c=0; 11 | int x=0; 12 | int y=n/2; 13 | do { 14 | c++; 15 | fz[x][y]=c; 16 | int new_x=(x-1+n)%n; 17 | int new_y=(y+1)%n; 18 | if (fz[new_x][new_y]>0){ 19 | new_x=(x+1)%n; 20 | new_y=y; 21 | } 22 | x=new_x; 23 | y=new_y; 24 | }while(c 2 | using namespace std; 3 | 4 | const int MAXN=200; 5 | int score[MAXN]; 6 | int grade[MAXN]; 7 | 8 | int n; 9 | 10 | int main(){ 11 | cin>>n; 12 | for(int i=0;i>score[i]>>grade[i]; 14 | } 15 | 16 | for(int i=1;igrade[j+1])){ 19 | swap(score[j],score[j+1]); 20 | swap(grade[j],grade[j+1]); 21 | } 22 | } 23 | 24 | for(int i=0;i 2 | using namespace std; 3 | const int MAXN=500; 4 | int n; 5 | int c[MAXN+1]; 6 | int dp[MAXN+1][MAXN+1]; 7 | 8 | int main(){ 9 | cin>>n; 10 | for(int i=1;i<=n;i++) cin>>c[i]; 11 | for(int i=1;i<=n;i++) dp[i][i]=1; 12 | for(int i=1;i<=n-1;i++) 13 | if (c[i]==c[i+1]) dp[i][i+1]=1; 14 | else dp[i][i+1]=2; 15 | for(int len=3;len<=n;len++) 16 | for(int i=1;i<=n-len+1;i++){ 17 | int j=i+len-1; 18 | dp[i][j]=dp[i][i]+dp[i+1][j]; 19 | for(int k=i+1;k 2 | using namespace std; 3 | struct node { 4 | int id; 5 | node *next; 6 | }; 7 | node *head; 8 | node *cur,*last; 9 | int n,k; 10 | int main(){ 11 | cin>>n>>k; 12 | head=new(node); 13 | head->next=NULL; 14 | last=head; 15 | for(int i=1;i<=n;i++){ 16 | cur=new(node); 17 | cur->next=NULL; 18 | cur->id=i; 19 | last->next=cur; 20 | last=cur; 21 | } 22 | last->next=head->next; 23 | last=head; 24 | cur=head->next; 25 | int i=0; 26 | while(cur!=NULL&&cur!=last){ 27 | i++; 28 | if (i==k){ 29 | cout<id<<' '; 30 | last->next=cur->next; 31 | i=0; 32 | cur=cur->next; 33 | }else { 34 | last=cur; 35 | cur=last->next; 36 | } 37 | } 38 | cout<id; 39 | system("pause"); 40 | } -------------------------------------------------------------------------------- /[基本算法]穷举/comb.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | FILE *fpin,*fpout; 4 | 5 | const int MAXN=20; 6 | int n,r; 7 | int combs[MAXN]; 8 | 9 | int main(){ 10 | fpin=fopen("comb.in","r"); 11 | fpout=fopen("comb.out","w"); 12 | 13 | fscanf(fpin,"%d %d",&n,&r); 14 | int pos=0; 15 | combs[pos]=1; 16 | while(combs[0]<=n-r+1){ 17 | while(posn&&pos>0){ 27 | pos--; 28 | combs[pos]++; 29 | } 30 | } 31 | } -------------------------------------------------------------------------------- /[基本算法]回溯法/book.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | ifstream fin("book.in"); 4 | ofstream fout("book.out"); 5 | 6 | const int MAXN=20; 7 | int n; 8 | int favorit[MAXN+1][MAXN+1]; 9 | char c; 10 | int ans; 11 | bool flag[MAXN+1]; 12 | 13 | void dfs(int i){ 14 | if (i>n) ans++; 15 | else { 16 | for(int j=1;j<=n;j++) 17 | if (!flag[j]&&favorit[i][j]){ 18 | flag[j]=true; 19 | dfs(i+1); 20 | flag[j]=false; 21 | } 22 | } 23 | } 24 | int main(){ 25 | fin>>n; 26 | for(int i=1;i<=n;i++) 27 | for(int j=1;j<=n;j++) { 28 | fin>>c; 29 | favorit[i][j]=c-'0'; 30 | } 31 | ans=0; 32 | dfs(1); 33 | fout< 2 | using namespace std; 3 | 4 | ifstream fin("cow.in"); 5 | ofstream fout("cow.out"); 6 | const int MAXN=100001; 7 | char s[MAXN]; 8 | int c[MAXN],w[MAXN]; 9 | 10 | int n; 11 | long long ans; 12 | int main(){ 13 | fin>>n; 14 | fin>>s; 15 | if (s[0]=='C') c[0]=1; 16 | else c[0]=0; 17 | for(int i=1;i=0;i--){ 25 | if (s[i]=='W') w[i]=w[i+1]+1; 26 | else w[i]=w[i+1]; 27 | } 28 | ans=0; 29 | for(int i=0;i 2 | #include 3 | #include 4 | using namespace std; 5 | const int MAXN=100000; 6 | int n; 7 | int a[MAXN+1],b[MAXN+1]; 8 | int dp[MAXN+1]; 9 | int map[MAXN+1]; 10 | int f[MAXN+1]; 11 | int len; 12 | 13 | int main(){ 14 | cin>>n; 15 | for(int i=1;i<=n;i++) { 16 | cin>>a[i]; 17 | map[a[i]]=i; 18 | } 19 | for(int i=1;i<=n;i++) { 20 | cin>>b[i]; 21 | f[i]=INT_MIN; 22 | } 23 | len=0; 24 | f[0]=0; 25 | for(int i=1;i<=n;i++){ 26 | if (map[b[i]]>f[len]) f[++len]=map[b[i]]; 27 | else { 28 | int k=upper_bound(f,f+len+1,map[b[i]])-f; 29 | f[k]=map[b[i]]; 30 | } 31 | } 32 | cout< 2 | using namespace std; 3 | 4 | const int MAXN=1000000; 5 | int height[MAXN]; 6 | int n,m,k; 7 | int main(){ 8 | cin>>n>>m; 9 | for(int i=0;i>height[i]; 10 | for(int i=0;i>k; 12 | int left=0; 13 | int right=n-1; 14 | int c=0; 15 | while(left<=right){ 16 | int mid=(left+right)/2; 17 | if (height[mid]==k){ 18 | c=1; 19 | for(int p=mid-1;p>=0&&height[p]==k;p--) c++; 20 | for(int p=mid+1;p 2 | #define ll long long 3 | const ll MOD=998244353; 4 | using namespace std; 5 | ll n,m; 6 | ll fast_pow(ll a,ll b){ 7 | ll ans=1; 8 | while(b){ 9 | if(b&1) ans=ans*a%MOD; 10 | a=a*a%MOD; 11 | b>>=1; 12 | } 13 | return ans; 14 | } 15 | 16 | ll inv(ll a,ll p){ 17 | return fast_pow(a,p-2); 18 | } 19 | 20 | ll f(ll n,ll m){ 21 | if (n==0&&m==0) return 0; 22 | if (n==0&&m==1) return 1; 23 | if (n>0&&m==0) return (1+(n-1)*n/2+2*(n-1)+1) % MOD; 24 | if (n>0&&m==1) return (n*(n+1)/2+2*n+1) % MOD; 25 | ll ret=((n+m+m*f(n,m-1)+n*f(n-1+m,1))%MOD)*inv(n+m,MOD) % MOD; 26 | return ret; 27 | } 28 | int main(){ 29 | cin>>n>>m; 30 | n=n%MOD; 31 | cout< 2 | #define ll long long 3 | const ll MOD=998244353; 4 | const ll MAXM=1000000; 5 | using namespace std; 6 | ll n,m; 7 | ll f[MAXM+1]; 8 | 9 | ll fast_pow(ll a,ll b){ 10 | ll ans=1; 11 | while(b){ 12 | if(b&1) ans=ans*a%MOD; 13 | a=a*a%MOD; 14 | b>>=1; 15 | } 16 | return ans; 17 | } 18 | 19 | ll inv(ll a,ll p){ 20 | return fast_pow(a,p-2); 21 | } 22 | int main(){ 23 | cin>>n>>m; 24 | n=n%MOD; 25 | f[0]=(1+(n-1)*n/2+2*(n-1)+1)%MOD; 26 | f[1]=(n*(n+1)/2+2*n+1)%MOD; 27 | if (m>=2){ 28 | for(int i=2;i<=m;i++){ 29 | f[i]=((n+i+n*(((n+i-1)*(n+i)/2+2*(n+i-1)+1)%MOD)+i*f[i-1])%MOD)*inv(n+i,MOD)%MOD; 30 | } 31 | } 32 | cout< 2 | #include 3 | using namespace std; 4 | 5 | ifstream fin("kaj.in"); 6 | ofstream fout("kaj.out"); 7 | 8 | const int MAXN=30000; 9 | int w,n; 10 | int t[MAXN]; 11 | int ship[MAXN]; 12 | 13 | int main(){ 14 | fin>>w>>n; 15 | for(int i=0;i>t[i]; 16 | sort(t,t+n,greater()); 17 | int cnt=1; 18 | ship[0]=w; 19 | for(int i=0;i=t[i]){ 23 | if (ship[k]!=w) ship[k]=0; 24 | else ship[k]-=t[i]; 25 | can=true; 26 | break; 27 | } 28 | if (!can){ 29 | cnt++; 30 | ship[cnt-1]=w-t[i]; 31 | } 32 | } 33 | fout< 2 | #include 3 | using namespace std; 4 | ifstream fin("max.in"); 5 | ofstream fout("max.out"); 6 | 7 | const int MAXN=20; 8 | string num[MAXN]; 9 | int n; 10 | 11 | bool cmp(string num1,string num2){ 12 | int l1=num1.length(); 13 | int l2=num2.length(); 14 | int i1=0,i2=0; 15 | while(1){ 16 | if (num1[i1]==num2[i2]){ 17 | i1++; 18 | i2++; 19 | if (i1==l1&&i2==l2) return false; 20 | else { 21 | i1=i1%l1; 22 | i2=i2%l2; 23 | } 24 | } 25 | else return (num1[i1]>num2[i2]); 26 | } 27 | } 28 | int main(){ 29 | fin>>n; 30 | for(int i=0;i>num[i]; 31 | sort(num,num+n,cmp); 32 | for(int i=0;i 2 | using namespace std; 3 | ifstream fin("matches.in"); 4 | ofstream fout("matches.out"); 5 | 6 | int n; 7 | int huocai[2223]={6,2,5,5,4,5,6,3,7,6,0}; 8 | int get_huocai(int x){ 9 | if (huocai[x]>0) return huocai[x]; 10 | else { 11 | int r=x % 10; 12 | int q=x / 10; 13 | int ret=huocai[r]+get_huocai(q); 14 | huocai[x]=ret; 15 | return ret; 16 | } 17 | } 18 | int main(){ 19 | fin>>n; 20 | int k=0; 21 | n-=4; 22 | for(int a=0;a<=1111;a++){ 23 | for(int b=a;b<=1111;b++){ 24 | int c=a+b; 25 | int total=get_huocai(a)+get_huocai(b)+get_huocai(c); 26 | if (total==n){ 27 | if (a==b) k++; 28 | else k+=2; 29 | } 30 | } 31 | } 32 | fout< 2 | #include 3 | #include 4 | 5 | using namespace std; 6 | ifstream fin("water.in"); 7 | ofstream fout("water.out"); 8 | 9 | struct person{ 10 | int id; 11 | int time; 12 | 13 | bool operator<(const person other) const{ 14 | return time>n; 23 | for(int i=0;i>p[i].time; 26 | } 27 | sort(p,p+n); 28 | float totalwait=0; 29 | float wait=0; 30 | for(int i=0;i 2 | #include 3 | 4 | using namespace std; 5 | ifstream fin("missile.in"); 6 | ofstream fout("missile.out"); 7 | const int MAXN=1000; 8 | int n; 9 | int high[MAXN]; 10 | int l1,l2; 11 | int d1[MAXN],d2[MAXN]; 12 | 13 | int main(){ 14 | fin>>n; 15 | for(int i=0;i>high[i]; 16 | l1=1; 17 | d1[0]=high[0]; 18 | l2=1; 19 | d2[0]=high[0]; 20 | 21 | for(int i=1;i())-d1; 25 | d1[k]=high[i]; 26 | } 27 | if (high[i]>d2[l2-1]) d2[l2++]=high[i]; 28 | else { 29 | int k=lower_bound(d2,d2+l2,high[i])-d2; 30 | d2[k]=high[i]; 31 | } 32 | } 33 | 34 | //输出 35 | fout< 2 | #include 3 | using namespace std; 4 | ifstream fin("choose.in"); 5 | ofstream fout("choose.out"); 6 | const int MAXN=100; 7 | vector graph[MAXN+1]; 8 | int dp_max[MAXN+1][MAXN+1]; 9 | int score[MAXN+1]; 10 | int n,m; 11 | void dp(int i){ 12 | dp_max[i][1]=score[i]; 13 | int s=graph[i].size(); 14 | for(int k=0;k0;w--) 18 | for(int v=w-1;v>0;v--) 19 | dp_max[i][w]=max(dp_max[i][w],dp_max[i][w-v]+dp_max[j][v]); 20 | } 21 | } 22 | int main(){ 23 | fin>>n>>m; 24 | for(int i=1;i<=n;i++){ 25 | int a,b; 26 | fin>>a>>b; 27 | graph[a].push_back(i); 28 | score[i]=b; 29 | } 30 | dp(0); 31 | fout< 3 | using namespace std; 4 | ifstream fin("energy.in"); 5 | ofstream fout("energy.out"); 6 | 7 | const int MAXN=1000; 8 | int head[MAXN*2]; 9 | int dp_max[MAXN*2][MAXN+1];//dp_max[i][j]表示以第i颗珠子为起始的,长度为j的区间(即[i,i+j-1])里,所有珠子合并所能得到的最大能量 10 | int n; 11 | 12 | int main(){ 13 | fin>>n; 14 | for(int i=0;i>head[i]; 16 | head[i+n]=head[i]; 17 | } 18 | int m=2*n-1; 19 | for(int j=2;j<=n;j++) //j为区间长度 20 | for(int i=0;ilastMax) lastMax=dp_max[i][n]; 28 | fout< 2 | #include 3 | 4 | using namespace std; 5 | const int MOD=1000000007; 6 | long long ops; 7 | 8 | long long a,b,h; 9 | int t; 10 | long long pow(long long x,int q){ 11 | long long ret=1; 12 | while(q>0){ 13 | if (q&1) ret=(ret*x)%MOD; 14 | x=(x*x)%MOD; 15 | q=q>>1; 16 | } 17 | return ret; 18 | } 19 | long long inv(long long x,int q){ 20 | return pow(x,q-2); 21 | } 22 | int main(){ 23 | scanf("%d",&t); 24 | for(int k=0;kb){ 27 | if (b!=1) ops=((pow(b,h)*a)%MOD+((((a-b)*(pow(b,h)-1))%MOD)*inv(b-1,MOD))%MOD)%MOD; 28 | else ops=((pow(b,h)*a)%MOD+((a-b)*h)%MOD)%MOD; 29 | }else { 30 | ops=(pow(b,h)*a)%MOD; 31 | } 32 | printf("%lld\n",ops); 33 | } 34 | } -------------------------------------------------------------------------------- /[洛谷题单]二叉堆与ST表/P3865.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using namespace std; 4 | const int MAXN=100000; 5 | const int MAXPOW=20; 6 | int a[MAXN+1]; 7 | int maxv[MAXN+1][MAXPOW+1]; 8 | int n,m; 9 | int query(int l,int r){ 10 | int ret=0; 11 | for(int j=MAXPOW;j>=0;j--){ 12 | if (l+(1< 2 | #include 3 | using namespace std; 4 | ifstream fin("book.in"); 5 | ofstream fout("book.out"); 6 | const int MAXM=500; 7 | const int INF=0x7fffffff; 8 | int m,k; 9 | int page[MAXM+1]; 10 | int totalPage[MAXM+1][MAXM+1]; 11 | int dp[MAXM+1][MAXM+1];//dp[i][j] 表示前i本书籍分配给前j个人所花的最短抄写时间 12 | 13 | int main(){ 14 | fin>>m>>k; 15 | for(int i=1;i<=m;i++) fin>>page[i]; 16 | 17 | for(int i=1;i<=m;i++) 18 | for(int j=i;j<=m;j++) 19 | totalPage[i][j]=totalPage[i][j-1]+page[j]; 20 | 21 | for(int i=1;i<=m;i++) 22 | for(int j=1;j<=i;j++) dp[i][j]=INF; 23 | 24 | for(int i=1;i<=m;i++) dp[i][1]=totalPage[1][i]; 25 | for(int i=2;i<=m;i++) 26 | for(int j=2;j<=i;j++) 27 | for(int p=j-1;p 2 | using namespace std; 3 | ifstream fin("chorus.in"); 4 | ofstream fout("chorus.out"); 5 | const int MAXN=1000; 6 | int n; 7 | int high[MAXN]; 8 | int dp[2][MAXN]; //dp[0][i] 表示编号 0——i-1 的学生中,以第i个学生身高为末尾的最长递增子序列 9 | //dp[1][i] 表示编号 i-1——n-1 的学生中,以第i个学生身高为起点的最长递减子序列 10 | int ans; 11 | 12 | int main(){ 13 | fin>>n; 14 | for(int i=0;i>high[i]; 15 | for(int i=0;i=0;i--) 24 | for(int k=n-1;k>i;k--) 25 | if (high[k]ans) ans=s; 30 | } 31 | fout< 2 | #include 3 | using namespace std; 4 | ifstream fin("strategi.in"); 5 | ofstream fout("strategi.out"); 6 | 7 | const int MAXN=1500; 8 | vector graph[MAXN+1]; 9 | int dp_min[MAXN+1][2]; 10 | int n; 11 | 12 | void dp(int x){ 13 | int s=graph[x].size(); 14 | int s0=0,s1=0; 15 | for(int k=0;k>n; 26 | for(int i=0;i>x>>b; 29 | for(int j=0;j>y; 32 | graph[x].push_back(y); 33 | } 34 | } 35 | dp(0); 36 | int ans=min(dp_min[0][0],dp_min[0][1]); 37 | fout< 2 | using namespace std; 3 | 4 | ifstream fin("bishop.in"); 5 | ofstream fout("bishop.out"); 6 | 7 | const int MAXN=20; 8 | int n,m,maxk; 9 | bool flag[MAXN][MAXN]; 10 | 11 | void MarkBackslash(int x,int y,bool val){ 12 | int b=y-x; 13 | for(int x_=0;x_=0&&y_n+m-2) return; 21 | for(int x=0;x=0&&ymaxk) maxk=k; 27 | MarkBackslash(x,y,true); 28 | SearchSlash(b+1,k); 29 | MarkBackslash(x,y,false); 30 | k--; 31 | } 32 | } 33 | } 34 | } 35 | int main(){ 36 | fin>>n>>m; 37 | SearchSlash(0,0); 38 | fout< 2 | #include 3 | using namespace std; 4 | ifstream fin("marathon.in"); 5 | ofstream fout("marathon.out"); 6 | struct CITY{ 7 | int x=0; 8 | int y=0; 9 | int distance_to(CITY other){ 10 | return abs(x-other.x)+abs(y-other.y); 11 | } 12 | }; 13 | const int MAXN=100001; 14 | CITY cities[MAXN]; 15 | int total_dis[MAXN]; 16 | int min_dis[MAXN]; 17 | 18 | int n; 19 | int main(){ 20 | fin>>n; 21 | for(int i=1;i<=n;i++){ 22 | fin>>cities[i].x>>cities[i].y; 23 | } 24 | total_dis[1]=0; 25 | for(int i=2;i<=n;i++) total_dis[i]=total_dis[i-1]+cities[i-1].distance_to(cities[i]); 26 | min_dis[1]=0; 27 | min_dis[2]=total_dis[2]; 28 | for(int i=3;i<=n;i++){ 29 | int d1=total_dis[i-2]+cities[i-2].distance_to(cities[i]); 30 | int d2=min_dis[i-1]+cities[i-1].distance_to(cities[i]); 31 | min_dis[i]=min(d1,d2); 32 | } 33 | fout< 2 | #include 3 | 4 | using namespace std; 5 | const int MAXN=20; 6 | int fz[MAXN+2][MAXN+2]; 7 | int dir_off[4][2]={{0,1},{-1,0},{0,-1},{1,0}}; 8 | 9 | int n; 10 | int main(){ 11 | cin>>n; 12 | for(int i=0;i 2 | using namespace std; 3 | ifstream fin("match.in"); 4 | ofstream fout("match.out"); 5 | 6 | const int MAXN=1000; 7 | int huocai[MAXN]; 8 | int n; 9 | int mi2[17]; 10 | 11 | int main(){ 12 | mi2[0]=1; 13 | for(int i=1;i<17;i++) mi2[i]=mi2[i-1]*2; 14 | fin>>n; 15 | for(int i=0;i>huocai[i]; 16 | int ret=huocai[0]; 17 | for(int i=1;i0) k--; 22 | for(int i=0;i0){ 25 | int old=huocai[i]; 26 | huocai[i]=huocai[i]^ret; 27 | inc=huocai[i]-old; 28 | fout<<-1*inc<<' '< 3 | using namespace std; 4 | const int MAXN=50000,key=10000; 5 | struct stack{ 6 | long ele[MAXN]; 7 | int top=0; 8 | void push(long x){ 9 | ele[top]=x; 10 | top++; 11 | } 12 | void pop(){ 13 | top--; 14 | } 15 | long get_top(){ 16 | return ele[top-1]; 17 | } 18 | bool empty(){ 19 | return top==0; 20 | } 21 | }; 22 | stack s; 23 | 24 | int main(){ 25 | int x; 26 | cin>>x; 27 | s.push(x); 28 | char op; 29 | while(cin>>op){ 30 | cin>>x; 31 | if (op=='*'){ 32 | int y=s.get_top(); 33 | x=(y*x)%key; 34 | s.pop(); 35 | s.push(x); 36 | }else if(op=='+') { 37 | s.push(x); 38 | } 39 | } 40 | int ret=0; 41 | while(!s.empty()){ 42 | x=s.get_top(); 43 | ret=(ret+x)%key; 44 | s.pop(); 45 | } 46 | cout< 3 | using namespace std; 4 | ifstream fin("kh.in"); 5 | ofstream fout("kh.out"); 6 | const int MAXN=100; 7 | string s; 8 | int dp_min[MAXN][MAXN]; 9 | 10 | int main(){ 11 | fin>>s; 12 | int len=s.length(); 13 | for(int i=0;i 2 | using namespace std; 3 | long long n,m,p; 4 | long long k; 5 | 6 | int main(){ 7 | cin>>n>>m>>k>>p; 8 | long long maxxi=min(k/p,m); 9 | bool can=false; 10 | long long remain=k-p*maxxi; 11 | long long remain_maxxi; 12 | if (n-p==0) { 13 | if (remain==0){ 14 | remain_maxxi=0; 15 | can=true; 16 | } 17 | }else { 18 | remain_maxxi=remain/(n-p); 19 | if (remain%(n-p)!=0) remain_maxxi++; 20 | if (remain_maxxi 2 | #include 3 | 4 | using namespace std; 5 | const int MAXN=50; 6 | int n; 7 | char c[MAXN+1]; 8 | int dp[MAXN+1][MAXN+1]; 9 | 10 | int main(){ 11 | int i=0; 12 | char a; 13 | while(cin>>a){ 14 | i++; 15 | c[i]=a; 16 | } 17 | n=i; 18 | for(int i=1;i<=n;i++) dp[i][i]=1; 19 | for(int i=1;i 2 | #include 3 | using namespace std; 4 | const int MAXN=100000; 5 | int a[MAXN+1],b[MAXN+1]; 6 | int c[MAXN+1]; 7 | int n; 8 | priority_queue maxheap; 9 | int main(){ 10 | cin>>n; 11 | for(int i=0;i>a[i]; 12 | for(int i=0;i>b[i]; 13 | int s=0; 14 | for(int i=0;i=maxheap.top()) break; 22 | else{ 23 | maxheap.pop(); 24 | maxheap.push(sum); 25 | } 26 | } 27 | } 28 | int i=0; 29 | while(!maxheap.empty()){ 30 | c[n-1-i]=maxheap.top(); 31 | maxheap.pop(); 32 | i++; 33 | } 34 | for(int i=0;i 2 | #include 3 | 4 | using namespace std; 5 | const int MAXN = 100000; 6 | int n; 7 | int high[MAXN]; 8 | int l1, l2; 9 | int d1[MAXN], d2[MAXN]; 10 | 11 | int main() { 12 | int i=0; 13 | long a; 14 | while(cin>>a){ 15 | high[i]=a; 16 | i++; 17 | } 18 | n=i; 19 | l1 = 1; 20 | d1[0] = high[0]; 21 | l2 = 1; 22 | d2[0] = high[0]; 23 | 24 | for (int i = 1; i < n; i++) { 25 | if (high[i] <= d1[l1 - 1]) 26 | d1[l1++] = high[i]; 27 | else { 28 | int k = upper_bound(d1, d1 + l1, high[i], greater()) - d1; 29 | d1[k] = high[i]; 30 | } 31 | if (high[i] > d2[l2 - 1]) 32 | d2[l2++] = high[i]; 33 | else { 34 | int k = lower_bound(d2, d2 + l2, high[i]) - d2; 35 | d2[k] = high[i]; 36 | } 37 | } 38 | 39 | //输出 40 | cout << l1 << endl << l2; 41 | } -------------------------------------------------------------------------------- /[洛谷题单]动态规划之动态规划的引入/P1434.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | const int MAXN=100; 4 | int r,c; 5 | int high[MAXN][MAXN]; 6 | int dp[MAXN][MAXN]; 7 | int direct_offset[4][2]={{0,1},{0,-1},{-1,0},{1,0}}; 8 | void tree_dp(int i,int j){ 9 | int maxsublength=0; 10 | for(int k=0;k<4;k++){ 11 | int newi=i+direct_offset[k][0]; 12 | int newj=j+direct_offset[k][1]; 13 | if (newi<0||newi>=r||newj<0||newj>=c) continue; 14 | if (high[i][j]<=high[newi][newj]) continue; 15 | if (dp[newi][newj]==0) tree_dp(newi,newj); 16 | maxsublength=max(maxsublength,dp[newi][newj]); 17 | } 18 | dp[i][j]=maxsublength+1; 19 | } 20 | int ans; 21 | int main(){ 22 | cin>>r>>c; 23 | for(int i=0;i>high[i][j]; 25 | for(int i=0;i 2 | using namespace std; 3 | const int MAXN=64; 4 | int n; 5 | unsigned long long k; 6 | int ans[MAXN+1]; 7 | unsigned long long mi2[MAXN+1]; 8 | void dfs(int i,int j,int dir){ 9 | if (i==0){ 10 | return; 11 | }else { 12 | if (dir==0){ 13 | if (k>=mi2[i-1]){ 14 | ans[i]=1; 15 | k=k-mi2[i-1]; 16 | dfs(i-1,k,1); 17 | }else { 18 | ans[i]=0; 19 | dfs(i-1,k,0); 20 | } 21 | }else { 22 | if (k>n>>k; 35 | mi2[0]=1; 36 | for(int i=1;i<=n;i++) mi2[i]=mi2[i-1]*2; 37 | dfs(n,k,0); 38 | for(int i=n;i>=1;i--) cout< 2 | #include 3 | #include 4 | using namespace std; 5 | ifstream fin("ticket.in"); 6 | ofstream fout("ticket.out"); 7 | char yy[5]={'a','e','i','o','u'}; 8 | bool isyy[256]; 9 | char letter[26]; 10 | int L,C; 11 | char ans[15]; 12 | int num; 13 | void dfs(int dep,int k){ 14 | if (dep>=L){ 15 | int yycount=0; 16 | for(int i=0;i0&&yycount<=L-2) { 18 | num++; 19 | if (num<=25000) { 20 | for(int i=0;i>L>>C; 34 | for(int i=0;i>letter[i]; 35 | for(int i=0;i<5;i++) isyy[int(yy[i])]=true; 36 | sort(letter,letter+C); 37 | dfs(0,0); 38 | system("pause"); 39 | } -------------------------------------------------------------------------------- /[洛谷题单]动态规划之线性状态动态规划/P5858.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | using namespace std; 5 | const int MAXN=5500; 6 | const int MAXW=5500; 7 | int n,w,s; 8 | long long a[MAXN+1]; 9 | long long totalNJD[MAXN+1][MAXW+1]; 10 | int main(){ 11 | scanf("%d %d %d",&n,&w,&s); 12 | for(int i=1;i<=n;i++) scanf("%lld",&a[i]); 13 | for(int i=1;i<=n;i++) 14 | for(int j=1;j<=w;j++) { 15 | totalNJD[i][j]=LONG_LONG_MIN; 16 | } 17 | totalNJD[1][1]=1*a[1]; 18 | for(int i=2;i<=n;i++){ 19 | for(int j=1;j<=min(i,w);j++){ 20 | for(int k=max(j-1,1);k<=min(j+s-1,w);k++){ 21 | if (totalNJD[i-1][k]==LONG_LONG_MIN) break; 22 | long long t=totalNJD[i-1][k]+j*a[i]; 23 | if (t>totalNJD[i][j]) totalNJD[i][j]=t; 24 | else break; 25 | } 26 | } 27 | } 28 | long long ans=LONG_LONG_MIN; 29 | for(int j=1;j<=w;j++) ans=max(ans,totalNJD[n][j]); 30 | printf("%lld",ans); 31 | } 32 | -------------------------------------------------------------------------------- /[洛谷题单]动态规划之树与图上的动态规划/P1613.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace std; 6 | const int MAXN=50; 7 | int n,m; 8 | bool can[MAXN+1][MAXN+1][64];//can[i][j][k]表示i到j是否有一条2^k次幂的路径 9 | int dis[MAXN+1][MAXN+1]; 10 | 11 | int main(){ 12 | cin>>n>>m; 13 | memset(dis,10,sizeof(dis)); 14 | for(int i=0;i>u>>v; 17 | dis[u][v]=1; 18 | can[u][v][0]=true; 19 | } 20 | 21 | for(int k=1;k<=64;k++) 22 | for(int i=1;i<=n;i++) 23 | for(int j=1;j<=n;j++) 24 | for(int o=1;o<=n;o++) 25 | if (can[i][o][k-1]&&can[o][j][k-1]) { 26 | can[i][j][k]=true; 27 | dis[i][j]=1; 28 | } 29 | //floyd求最短路径 30 | for(int k=1;k<=n;k++) 31 | for(int i=1;i<=n;i++) 32 | for(int j=1;j<=n;j++) 33 | if (dis[i][k]+dis[k][j] 2 | #include 3 | using namespace std; 4 | const int MAXN=100000; 5 | int a[MAXN+1]; 6 | int n; 7 | priority_queue maxheap; 8 | priority_queue,greater > minheap; 9 | 10 | int main(){ 11 | cin>>n; 12 | for(int i=1;i<=n;i++) cin>>a[i]; 13 | int smin=0; 14 | for(int i=1;i<=n;i++){ 15 | if (smin==0) { 16 | minheap.push(a[i]); 17 | smin++; 18 | }else { 19 | if (a[i]<=minheap.top()) { 20 | maxheap.push(a[i]); 21 | }else { 22 | minheap.push(a[i]); 23 | smin++; 24 | } 25 | } 26 | if (smin<((i+1)/2)){ 27 | minheap.push(maxheap.top()); 28 | smin++; 29 | maxheap.pop(); 30 | }else if (smin>((i+1)/2)){ 31 | maxheap.push(minheap.top()); 32 | smin--; 33 | minheap.pop(); 34 | } 35 | if (i%2>0) cout< 2 | #include 3 | using namespace std; 4 | const int MAXN=1000000; 5 | struct Edge{ 6 | int u,v,w; 7 | }; 8 | Edge edges[MAXN]; 9 | vector G[MAXN+1]; 10 | int parent[MAXN+1]; 11 | int size[MAXN+1]; 12 | int n; 13 | long long sum; 14 | 15 | void dfs(int u,int fa){ 16 | size[u]=1; 17 | parent[u]=fa; 18 | for(int k=0;k>n; 28 | for(int i=0;i>a>>b>>c; 31 | edges[i]={a,b,c}; 32 | G[a].push_back(b); 33 | G[b].push_back(a); 34 | } 35 | dfs(1,0); 36 | for(int i=0;i 2 | #include 3 | #include 4 | using namespace std; 5 | const int MAXN=150000; 6 | struct Task{ 7 | int t1; 8 | int t2; 9 | bool operator<(const Task other)const{ 10 | return t2 heap; 15 | int sumt; 16 | int n,ans; 17 | 18 | int main(){ 19 | cin>>n; 20 | for(int i=0;i>tasks[i].t1>>tasks[i].t2; 22 | } 23 | sort(tasks,tasks+n); 24 | sumt=0; 25 | ans=0; 26 | for(int i=0;i 3 | #include 4 | using namespace std; 5 | ifstream fin("aniv.in"); 6 | ofstream fout("aniv.out"); 7 | 8 | const int MAXN=6000; 9 | int happy[MAXN+1]; 10 | vector graph[MAXN+1]; 11 | int dp_max[MAXN+1][2]; 12 | int n; 13 | int parent[MAXN+1]; 14 | 15 | void dp(int x){ 16 | int s=graph[x].size(); 17 | int s0=0,s1=0; 18 | for(int k=0;k>n; 29 | for(int i=1;i<=n;i++) fin>>happy[i]; 30 | int l,k; 31 | fin>>l>>k; 32 | while(l>0&&k>0){ 33 | graph[k].push_back(l); 34 | parent[l]=k; 35 | fin>>l>>k; 36 | } 37 | 38 | int cur=1; 39 | while(parent[cur]>0) cur=parent[cur]; 40 | int root=cur; 41 | dp(root); 42 | fout< 3 | using namespace std; 4 | ifstream fin("TREE.in"); 5 | ofstream fout("TREE.out"); 6 | 7 | const int MAXN=30; 8 | long dp_max[MAXN+1][MAXN+1]; 9 | int dp_path[MAXN+1][MAXN+1]; 10 | 11 | int a[MAXN+1]; 12 | int n; 13 | 14 | long dp(int i,int j){ 15 | if (dp_max[i][j]>0) return dp_max[i][j]; 16 | if (i>j) return 1; 17 | if (i==j) return a[i]; 18 | for(int r=i;r<=j;r++){ 19 | long t=dp(i,r-1)*dp(r+1,j)+a[r]; 20 | if (t>dp_max[i][j]){ 21 | dp_max[i][j]=t; 22 | dp_path[i][j]=r; 23 | } 24 | } 25 | return dp_max[i][j]; 26 | } 27 | void root_first_visit(int i,int j){ 28 | if (i>j) return; 29 | if (i==j) fout<>n; 39 | for(int i=1;i<=n;i++) fin>>a[i]; 40 | fout< 3 | using namespace std; 4 | ifstream fin("transfer.in"); 5 | ofstream fout("transfer.out"); 6 | 7 | const int MAXN=50000; 8 | int factorSum[MAXN+1]; 9 | int maxLen[MAXN+1],secondMaxLen[MAXN+1];//maxLen[i]表示以i为根的子树中, 10 | //i到叶子结点的最长路径,secondMaxLen[i]是i到叶子结点的次长路径 11 | 12 | int n; 13 | 14 | int main(){ 15 | fin>>n; 16 | for(int i=1;i<=n;i++) 17 | for(int j=2;j<=n/i;j++) 18 | factorSum[i*j]+=i; 19 | for(int i=n;i>=1;i--){//大的数总是挂在小的数下,所以从大到小遍历计算 20 | if (factorSum[i]maxLen[p]){ 23 | secondMaxLen[p]=maxLen[p]; 24 | maxLen[p]=maxLen[i]+1; 25 | }else if (maxLen[i]+1>secondMaxLen[p]){ 26 | secondMaxLen[p]=maxLen[i]+1; 27 | } 28 | } 29 | } 30 | int ans=0; 31 | for(int i=n;i>=1;i--){ 32 | if (maxLen[i]+secondMaxLen[i]>ans) ans=maxLen[i]+secondMaxLen[i]; 33 | } 34 | fout< 2 | #include 3 | #include 4 | using namespace std; 5 | const int MAXN=10000; 6 | const int MAXK=10000; 7 | 8 | int p[MAXK],t[MAXK]; 9 | int dp[MAXN+2]; 10 | bool calculted[MAXN+2]; 11 | vector taskTree[MAXN+1]; 12 | 13 | int n,k; 14 | void tree_dp(int i){ 15 | if (i>n||calculted[i]) return; 16 | int size=taskTree[i].size(); 17 | if (size==0){ 18 | tree_dp(i+1); 19 | dp[i]=dp[i+1]; 20 | }else { 21 | dp[i]=n; 22 | for(int j=0;j>n>>k; 33 | for(int i=0;i>p[i]>>t[i]; 35 | taskTree[p[i]].push_back(i); 36 | } 37 | 38 | fill(calculted,calculted+n+1,false); 39 | tree_dp(1); 40 | cout< 2 | using namespace std; 3 | ifstream fin("missile.in"); 4 | ofstream fout("missile.out"); 5 | const int MAXN=1000; 6 | int n; 7 | int high[MAXN]; 8 | int dp[MAXN];//dp[i] 表示前 i 枚导弹,在第 i 枚被拦截的前提下,能拦截的最大导弹数 9 | int ans1,ans2; 10 | int minHigh[MAXN];//minHigh[k] 记录第 k 套系统拦截导弹的最低高度 11 | 12 | int main(){ 13 | fin>>n; 14 | for(int i=0;i>high[i]; 15 | //动规计算出 dp[i] 16 | for(int i=0;i=high[i]) dp[i]=max(dp[i],dp[k]+1); 20 | } 21 | //找出最大的 dp[i] 22 | for(int i=0;ians1) ans1=dp[i]; 24 | 25 | //计算需要多少套拦截系统 26 | int ans2=1; 27 | minHigh[0]=high[0]; 28 | 29 | for(int i=1;i 2 | #include 3 | 4 | using namespace std; 5 | 6 | const int MAXN=20; 7 | int fz[MAXN][MAXN]; 8 | int n; 9 | 10 | int main(){ 11 | cin>>n; 12 | int c=0; 13 | bool dir=1; 14 | for(int b=n-1;b>=-(n-1);b--){ 15 | switch (dir){ 16 | case 0: 17 | for(int x=0;x=0&&y=0;x--){ 27 | int y=x+b; 28 | if (y>=0&&y 3 | using namespace std; 4 | ifstream fin("test.in"); 5 | ofstream fout("test.out"); 6 | 7 | const int MAXLEVEL=31; 8 | int f[MAXLEVEL+1][10];//f[i][j] 表示高度为i的完全10叉树中当根结点为j时,由根结点到叶结点的路径所组成的数是不降数的个数 9 | int a,b; 10 | 11 | void dp(){ 12 | for(int i=0;i<=9;i++) f[0][i]=1; 13 | for(int i=1;i<=MAXLEVEL;i++) 14 | for(int j=0;j<=9;j++){ 15 | for(int k=j;k<=9;k++) f[i][j]+=f[i-1][k]; 16 | } 17 | } 18 | 19 | int calc(int x){ 20 | int t[MAXLEVEL+1]={0}; 21 | int k=0; 22 | while(x>0){ 23 | int d=x % 10; 24 | t[k]=d; 25 | k++; 26 | x= x / 10; 27 | } 28 | int tot=0,ans=0; 29 | int i=max(k-1,0); 30 | for(;i>=0;i--){ 31 | int d=t[i]; 32 | if (d>a) { 43 | fin>>b; 44 | int n1=calc(a-1); 45 | int n2=calc(b); 46 | fout< 2 | #include 3 | using namespace std; 4 | const int MAXN=50; 5 | int n,c; 6 | int w[MAXN+1],p[MAXN+1]; 7 | int sumw[MAXN+1]; 8 | int dp[MAXN+1][MAXN+1][2];//dp[i][j]表示关掉区间[i,j]里的灯时,所有的灯耗费的电量 9 | 10 | int main(){ 11 | cin>>n>>c; 12 | for(int i=1;i<=n;i++) { 13 | cin>>p[i]>>w[i]; 14 | sumw[i]=sumw[i-1]+w[i]; 15 | } 16 | for(int i=1;i<=n;i++){ 17 | int t=abs(p[i]-p[c]); 18 | dp[i][i][0]=t*sumw[n]; 19 | dp[i][i][1]=t*sumw[n]; 20 | } 21 | 22 | for(int len=2;len<=n;len++){ 23 | for(int i=1;i<=n-len+1;i++){ 24 | int j=i+len-1; 25 | int v1=dp[i+1][j][0]+(p[i+1]-p[i])*(sumw[i]+sumw[n]-sumw[j]); 26 | int v2=dp[i+1][j][1]+(p[j]-p[i])*(sumw[i]+sumw[n]-sumw[j]); 27 | dp[i][j][0]=min(v1,v2); 28 | v1=dp[i][j-1][0]+(p[j]-p[i])*(sumw[i-1]+sumw[n]-sumw[j-1]); 29 | v2=dp[i][j-1][1]+(p[j]-p[j-1])*(sumw[i-1]+sumw[n]-sumw[j-1]); 30 | dp[i][j][1]=min(v1,v2); 31 | } 32 | } 33 | cout< 2 | using namespace std; 3 | string s; 4 | int m,d; 5 | int monday[13]={0,31,28,31,30,31,60,31,31,30,31,30,31}; 6 | int main(){ 7 | cin>>s; 8 | m=(s[0]-'0')*10+(s[1]-'0'); 9 | d=(s[3]-'0')*10+(s[4]-'0'); 10 | int tl=s[1]-'0'; 11 | int th=s[0]-'0'; 12 | if (d>31){ 13 | if (m>12) cout<<2; 14 | else if (m>0) cout<<1; 15 | else cout<<2; 16 | }else if (d>28){ 17 | if (m>12) { 18 | if (d<=monday[tl]) cout<<1; 19 | else if (tl+10<=12&&d<=monday[tl+10]) cout<<1; 20 | else if (th*10+1<=12&&d<=monday[th*10+1]) cout<<1; 21 | else if (th*10+2<=12&&d<=monday[th*10+2]) cout<<1; 22 | else cout<<2; 23 | } 24 | else if (m>0) { 25 | if (d>monday[m]) cout<<1; 26 | else cout<<0; 27 | } 28 | else cout<<1; 29 | 30 | }else if (d>0){ 31 | if (m>12) cout<<1; 32 | else if (m>0) cout<<0; 33 | else cout<<1; 34 | }else { 35 | if (m>12) cout<<2; 36 | else if (m>0) cout<<1; 37 | else cout<<2; 38 | } 39 | } -------------------------------------------------------------------------------- /[洛谷题单]动态规划之线性状态动态规划/P1020.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | const int MAXN=100000; 4 | int n; 5 | int high[MAXN]; 6 | int dp[MAXN];//dp[i] 表示前 i 枚导弹,在第 i 枚被拦截的前提下,能拦截的最大导弹数 7 | int ans1,ans2; 8 | int minHigh[MAXN];//minHigh[k] 记录第 k 套系统拦截导弹的最低高度 9 | 10 | int main(){ 11 | int i=0; 12 | int a; 13 | while(cin>>a){ 14 | high[i]=a; 15 | i++; 16 | } 17 | n=i; 18 | //动规计算出 dp[i] 19 | for(int i=0;i=high[i]) dp[i]=max(dp[i],dp[k]+1); 23 | } 24 | //找出最大的 dp[i] 25 | for(int i=0;ians1) ans1=dp[i]; 27 | 28 | //计算需要多少套拦截系统 29 | int ans2=1; 30 | minHigh[0]=high[0]; 31 | 32 | for(int i=1;i 2 | #include 3 | #define ll long long 4 | using namespace std; 5 | const int MAXN=40; 6 | const long MAXK=1200000; 7 | ll values[MAXK]; 8 | int vcount; 9 | int n; 10 | ll m; 11 | ll price[MAXN+1]; 12 | ll ans=0; 13 | void lsearch(int pos,ll val){ 14 | if (val>0&&val<=m){ 15 | ans++; 16 | values[vcount]=val; 17 | vcount++; 18 | } 19 | if (val>m) return; 20 | for(int i=pos+1;i<=n/2;i++){ 21 | if (val+price[i]>m) break; 22 | lsearch(i,val+price[i]); 23 | } 24 | } 25 | void rsearch(int pos,ll val){ 26 | if (val>0&&val<=m){ 27 | ans++; 28 | int i=upper_bound(values,values+vcount,m-val)-values; 29 | if (i>=0) ans+=i; 30 | } 31 | if (val>m) return; 32 | for(int i=pos+1;i<=n;i++){ 33 | if (val+price[i]>m) break; 34 | rsearch(i,val+price[i]); 35 | } 36 | } 37 | int main(){ 38 | cin>>n>>m; 39 | for(int i=1;i<=n;i++) cin>>price[i]; 40 | sort(price,price+n+1); 41 | lsearch(0,0); 42 | sort(values,values+vcount); 43 | rsearch(n/2,0); 44 | ans++; 45 | cout< 2 | using namespace std; 3 | struct node 4 | { 5 | int id; 6 | node *prev,*next; 7 | }; 8 | 9 | int n,m; 10 | node *head; 11 | node *last; 12 | node *cur; 13 | 14 | int main(){ 15 | cin>>n>>m; 16 | head=new(node); 17 | head->next=NULL; 18 | head->prev=NULL; 19 | last=head; 20 | for(int i=1;i<=n;i++){ 21 | cur=new(node); 22 | cur->id=i; 23 | cur->next=NULL; 24 | cur->prev=NULL; 25 | last->next=cur; 26 | cur->prev=last; 27 | last=cur; 28 | } 29 | node *p=head->next; 30 | 31 | int i=0; 32 | int d=0; 33 | while(p!=NULL&&p!=head){ 34 | i++; 35 | if (i==m){ 36 | if (p->prev!=NULL) p->prev->next=p->next; 37 | if (p->next!=NULL) p->next->prev=p->prev; 38 | i=0; 39 | } 40 | if (d==0){ 41 | if (p->next==NULL){ 42 | d=1; 43 | p=p->prev; 44 | }else p=p->next; 45 | }else { 46 | if (p->prev==head){ 47 | d=0; 48 | p=p->next; 49 | }else p=p->prev; 50 | } 51 | } 52 | cout<next->id; 53 | } 54 | 55 | -------------------------------------------------------------------------------- /[提高训练]动态规划之树型DP/apple.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace std; 5 | 6 | ifstream fin("apple.in"); 7 | ofstream fout("apple.out"); 8 | const int MAXN=100; 9 | struct node 10 | { 11 | int next; 12 | int applenum; 13 | }; 14 | 15 | vector graph[MAXN+1]; 16 | int parent[MAXN+1]; 17 | int dp_max[MAXN+1][MAXN+1]; 18 | int n,q; 19 | void dp(int x){ 20 | int s=graph[x].size(); 21 | for(int k=0;k0;w--) 28 | for(int v=w-1;v>=0;v--) 29 | dp_max[x][w]=max(dp_max[x][w],dp_max[x][w-v-1]+dp_max[y][v]+n.applenum); 30 | } 31 | } 32 | } 33 | 34 | int main(){ 35 | fin>>n>>q; 36 | for(int i=1;i<=n-1;i++){ 37 | int a,b,c; 38 | fin>>a>>b>>c; 39 | node n1={b,c}; 40 | graph[a].push_back(n1); 41 | node n2={a,c}; 42 | graph[b].push_back(n2); 43 | } 44 | parent[1]=0; 45 | dp(1); 46 | //for(int i=0;i<=q;i++) cout< 2 | using namespace std; 3 | ifstream fin("meeting.in"); 4 | ofstream fout("meeting.out"); 5 | 6 | const int MAXN=16; 7 | int g_bls[MAXN+1][MAXN+1]; 8 | int g_als[MAXN+1][MAXN+1]; 9 | 10 | bool times[150010]; 11 | 12 | int n,m; 13 | int min_time=150010; 14 | 15 | void dfs_bls(int dep,int i,int time){ 16 | if (i==n){ 17 | times[time]=true; 18 | }else if (dep>n-1) return; 19 | else { 20 | for(int j=1;j<=n;j++){ 21 | if (g_bls[i][j]>0) dfs_bls(dep+1,j,time+g_bls[i][j]); 22 | } 23 | } 24 | } 25 | 26 | void dfs_als(int dep,int i,int time){ 27 | if (i==n){ 28 | if (times[time]&&timen-1) return; 32 | else { 33 | for(int j=1;j<=n;j++){ 34 | if (g_als[i][j]>0) dfs_als(dep+1,j,time+g_als[i][j]); 35 | } 36 | } 37 | } 38 | int main(){ 39 | fin>>n>>m; 40 | for(int i=0;i>a>>b>>c>>d; 43 | g_bls[a][b]=c; 44 | g_als[a][b]=d; 45 | } 46 | dfs_bls(1,1,0); 47 | dfs_als(1,1,0); 48 | if (min_time==150010) fout<<"IMPOSSIBLE"; 49 | else fout< 2 | #include 3 | #include 4 | 5 | using namespace std; 6 | const int MAXN=1000; 7 | const int MAXV=20000; 8 | int n; 9 | int high[MAXV+1]; 10 | int solutions[MAXN][MAXV*2]; 11 | vector gc[MAXN]; 12 | 13 | int main(){ 14 | cin>>n; 15 | for(int i=0;i>high[i]; 17 | } 18 | for(int i=1;i 2 | using namespace std; 3 | ifstream fin("mas.in"); 4 | ofstream fout("mas.out"); 5 | 6 | int u; 7 | bool used[10]; 8 | int ans[10]; 9 | int sum[10][2]; 10 | int pailei[10][10]; 11 | 12 | void dfs(int i){ 13 | if (i>=u){ 14 | bool can=true; 15 | for(int j=0;j>u; 44 | for(int i=0;i>sum[i][0]>>sum[i][1]; 46 | for(int j=0;j>pailei[i][j]; 47 | } 48 | dfs(0); 49 | system("pause"); 50 | } -------------------------------------------------------------------------------- /[洛谷题单]动态规划之状态压缩动态规划/P1879.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace std; 5 | const int MAXM=12; 6 | const int MAXN=12; 7 | const int MAXS=4095;//2^12-1 8 | const int K=100000000; 9 | int dp[MAXM+1][MAXS+1]; 10 | int flag[MAXM+1]; 11 | int m,n; 12 | int lastS; 13 | bool can(int s,int i){ 14 | if (s&(s>>1)) return false; 15 | else if ((~flag[i])&s) return false; 16 | else return true; 17 | } 18 | bool conflict(int s1,int s2){ 19 | if (s1&s2) return true; 20 | return false; 21 | } 22 | 23 | int main(){ 24 | cin>>m>>n; 25 | lastS=pow(2,n)-1; 26 | for(int i=1;i<=m;i++){ 27 | int mi=1; 28 | for(int j=1;j<=n;j++){ 29 | int c; 30 | cin>>c; 31 | flag[i]+=mi*c; 32 | mi=mi*2; 33 | } 34 | } 35 | dp[0][0]=1; 36 | for(int i=1;i<=m;i++){ 37 | for(int s1=0;s1<=lastS;s1++){ 38 | if (!can(s1,i)) continue; 39 | for(int s2=0;s2<=lastS;s2++){ 40 | if (!can(s2,i-1)) continue; 41 | if (!conflict(s1,s2)) dp[i][s1]=(dp[i][s1]+dp[i-1][s2]) % K; 42 | } 43 | } 44 | } 45 | int ans=0; 46 | for(int s=0;s<=lastS;s++) ans=(ans+dp[m][s])%K; 47 | cout< 2 | #include 3 | #include 4 | 5 | using namespace std; 6 | const int MAXN=210; 7 | const int MAXQ=50000; 8 | const int INF=0x3fffffff; 9 | 10 | int n,m,q; 11 | int bt[MAXN]; 12 | int dist[MAXN][MAXN]; 13 | //对floyd算法进行改造,每次通过当前已重建的村庄u进行松弛操作 14 | void update(int u){ 15 | for(int i=0;it||bt[y]>t) printf("%d\n",-1); 36 | else { 37 | while(bt[now]<=t&&now 3 | #include 4 | 5 | using namespace std; 6 | ifstream fin("separation.in"); 7 | ofstream fout("separation.out"); 8 | const int MAXN=300; 9 | int dp_max[MAXN+1][MAXN+1]; 10 | int dp_path[MAXN+1][MAXN+1]; 11 | 12 | int a[MAXN+1]; 13 | int n; 14 | vector tree[MAXN]; 15 | 16 | void search(int i,int j,int deep){ 17 | if (i>=j) return; 18 | else { 19 | int k=dp_path[i][j]; 20 | tree[deep].push_back(k); 21 | search(i,k,deep+1); 22 | search(k+1,j,deep+1); 23 | } 24 | } 25 | int main(){ 26 | fin>>n; 27 | for(int i=1;i<=n;i++) fin>>a[i]; 28 | 29 | for(int len=2;len<=n;len++){ 30 | for(int i=1;i<=n-len+1;i++){ 31 | int j=i+len-1; 32 | for(int k=i;kdp_max[i][j]){ 35 | dp_max[i][j]=t; 36 | dp_path[i][j]=k; 37 | } 38 | } 39 | } 40 | } 41 | fout< 3 | using namespace std; 4 | 5 | const int MAXN=20000; 6 | struct union_find_set{ 7 | int father[MAXN+1]; 8 | void make_set(){ 9 | for(int i=1;i<=MAXN;i++) father[i]=i; 10 | } 11 | int find_set(int x){ 12 | while(father[x]!=x) x=father[x]; 13 | return x; 14 | } 15 | void union_set(int x,int y){ 16 | int hx=find_set(x); 17 | int hy=find_set(y); 18 | while(father[y]!=y){ 19 | int p=father[y]; 20 | father[y]=hx; 21 | y=p; 22 | } 23 | father[hy]=hx; 24 | } 25 | }; 26 | 27 | union_find_set ufs; 28 | void getd(int &x){ 29 | char c; 30 | for(c=getc(stdin);c<'0'||c>'9';c=getc(stdin)); 31 | 32 | for(x=0;c>='0'&&c<='9';c=getc(stdin)) 33 | x=x*10+c-'0'; 34 | } 35 | int n,m,q; 36 | int main(){ 37 | getd(n);getd(m); 38 | ufs.make_set(); 39 | for(long i=0;i 2 | using namespace std; 3 | 4 | ifstream fin("whatbase.in"); 5 | ofstream fout("whatbase.out"); 6 | 7 | int k,a,b; 8 | 9 | long long ndigit(int m,int n){ 10 | long long ret=0; 11 | int p=m; 12 | int mi=1; 13 | while(p>0){ 14 | int q=p%10; 15 | ret+=q*mi; 16 | p=p/10; 17 | mi=mi*n; 18 | } 19 | return ret; 20 | } 21 | 22 | int main(){ 23 | fin>>k; 24 | for(int i=0;i>a>>b; 26 | for(int x=10;x<=15000;x++){ 27 | long long m1=ndigit(a,x); 28 | int left,right; 29 | if (a>b){ 30 | left=x+1; 31 | right=15000; 32 | }else { 33 | left=10; 34 | right=x; 35 | } 36 | bool find=false; 37 | while(left<=right){ 38 | int y=(left+right)/2; 39 | long long m2=ndigit(b,y); 40 | if (m2==m1){ 41 | fout<m1){ 45 | right=y-1; 46 | }else { 47 | left=y+1; 48 | } 49 | } 50 | if (find) break; 51 | } 52 | } 53 | } -------------------------------------------------------------------------------- /[c++基础]结构体的定义和应用/birthday.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace std; 5 | 6 | const int MAXN=180; 7 | struct Name{ 8 | string content; 9 | int len; 10 | bool operator <(const Name other) const { 11 | if (len>n; 38 | for(int i=0;i>name>>m>>d; 40 | counts[m][d].add(name); 41 | } 42 | bool has=false; 43 | for(int i=1;i<=12;i++) 44 | for(int j=1;j<=31;j++){ 45 | if (counts[i][j].num>=2) { 46 | has=true; 47 | cout< 2 | #include 3 | #include 4 | 5 | using namespace std; 6 | const int MAXN=5500; 7 | const int MAXW=5500; 8 | int n,w,s; 9 | long long a[MAXN+1]; 10 | long long totalNJD[MAXN+1][MAXW+1]; 11 | long long val[MAXW+1]; 12 | int pos[MAXW+1]; 13 | 14 | int main(){ 15 | scanf("%d %d %d",&n,&w,&s); 16 | for(int i=1;i<=n;i++) scanf("%lld",&a[i]); 17 | for(int i=1;i<=n;i++) 18 | for(int j=1;j<=w;j++) { 19 | totalNJD[i][j]=LONG_LONG_MIN; 20 | } 21 | totalNJD[1][1]=1*a[1]; 22 | for(int i=2;i<=n;i++){ 23 | int left=1,right=1; 24 | int last=min(i-1,w); 25 | val[left]=totalNJD[i-1][last]; 26 | pos[left]=last; 27 | for(int j=min(i,w);j;j--){ 28 | while(pos[left]>j+s-1&&left<=right) left++; 29 | if (j>1){ 30 | while(val[right] 2 | #include 3 | #include 4 | using namespace std; 5 | const int MAXN=500000; 6 | int n,m,r; 7 | vector tree[MAXN+1]; 8 | int f[MAXN+1][21]; 9 | int deep[MAXN+1]; 10 | 11 | void pre(int u,int fa){ 12 | deep[u]=deep[fa]+1; 13 | f[u][0]=fa; 14 | for(int k=0;k=0;i--) 24 | if (deep[f[x][i]]>=deep[y]) x=f[x][i]; 25 | if (x==y) return x; 26 | for(int i=20;i>=0;i--){ 27 | if (f[x][i]!=f[y][i]){ 28 | x=f[x][i]; 29 | y=f[y][i]; 30 | } 31 | } 32 | return f[x][0]; 33 | } 34 | int main(){ 35 | scanf("%d %d %d",&n,&m,&r); 36 | for(int i=1;i 3 | #include 4 | using namespace std; 5 | ifstream fin("zoo.in"); 6 | ofstream fout("zoo.out"); 7 | 8 | const int MAXN=10000; 9 | const int MAXC=50000; 10 | const int INF=0x7fffffff; 11 | 12 | int dp[MAXN+1][32]; 13 | int num[MAXN+1][32]; 14 | int e,f,l; 15 | int fflag,lflag; 16 | int n,c; 17 | 18 | int main(){ 19 | fin>>n>>c; 20 | for(int i=1;i<=c;i++){ 21 | fin>>e>>f>>l; 22 | fflag=0;lflag=0; 23 | for(int j=0;j>x; 26 | x=(x+n-e)%n; 27 | fflag+=1<>y; 32 | y=(y+n-e)%n; 33 | lflag+=1< 2 | using namespace std; 3 | 4 | const int MAXN=65; 5 | int num[MAXN*50+1]; 6 | int n; 7 | int maxv,minv; 8 | int sum; 9 | int ans; 10 | void dfs(int wait,int alreadylen,int needlen,int prelen){ 11 | if (wait==0){//已经拼完所需要的木棍数 12 | cout<=minv;k--){//从前一小段的长度到最小长度枚举 19 | if (num[k]==0||alreadylen+k>needlen) continue; 20 | num[k]--; 21 | dfs(wait,alreadylen+k,needlen,k); 22 | num[k]++; 23 | if (alreadylen==0||alreadylen+k==needlen) break;//拼接一根的第一段和最后一段不需要继续枚举其他值 24 | } 25 | } 26 | } 27 | } 28 | int main(){ 29 | cin>>n; 30 | for(int i=0;i>k; 33 | if (k<=50){ 34 | sum+=k; 35 | num[k]++;//每个长度的段数 36 | minv=min(minv,k); 37 | maxv=max(maxv,k); 38 | } 39 | } 40 | ans=maxv; 41 | while(ans<=sum/2){ 42 | if (sum%ans==0){ 43 | int k=sum / ans; 44 | dfs(k,0,ans,maxv); 45 | } 46 | ans++; 47 | } 48 | cout< 3 | #include 4 | #include 5 | using namespace std; 6 | const int MAXN=50000; 7 | vector G[MAXN+1]; 8 | int size[MAXN+1];//指定根后,表示以i为根的子树下共有多少个节点 9 | int dp_sum[MAXN+1];//表示以i为根时,整个树中其他节点到i的距离之和 10 | //选定根节点后,第一次树型DP,计算出size[i]和dp_sum[根节点],这里的根节点一般选1 11 | void dfs(int u,int fa){ 12 | size[u]=1; 13 | dp_sum[u]=0; 14 | for(int k=0;k>n; 36 | for(int i=1;i>a>>b; 39 | G[a].push_back(b); 40 | G[b].push_back(a); 41 | } 42 | dfs(1,0); 43 | dfs1(1,0,1); 44 | int ans=INT_MAX; 45 | int node=0; 46 | for(int u=1;u<=n;u++){ 47 | if (ans>dp_sum[u]){ 48 | ans=dp_sum[u]; 49 | node=u; 50 | } 51 | } 52 | cout< 2 | using namespace std; 3 | const int MOD=1000000007; 4 | const int MAXN=500000; 5 | long long a[MAXN+1],b[MAXN+1]; 6 | long long sa[MAXN+1],sb[MAXN+1];//从1向n的累加 7 | long long totalSa[MAXN+1],totalSb[MAXN+1],totalSaSb[MAXN+1];//从n向1的累加 8 | int n; 9 | long long ans; 10 | long long add(long long a,long long b){ 11 | a=a%MOD; 12 | b=b%MOD; 13 | return (a+b)%MOD; 14 | } 15 | long long mul(long long a,long long b){ 16 | a=a%MOD; 17 | b=b%MOD; 18 | return (a*b)%MOD; 19 | } 20 | int main(){ 21 | cin>>n; 22 | for(int i=1;i<=n;i++){ 23 | cin>>a[i]; 24 | sa[i]=(sa[i-1]+a[i]) % MOD; 25 | } 26 | for(int i=1;i<=n;i++){ 27 | cin>>b[i]; 28 | sb[i]=(sb[i-1]+b[i]) % MOD; 29 | } 30 | totalSa[n]=sa[n]; 31 | totalSb[n]=sb[n]; 32 | totalSaSb[n]=mul(sa[n],sb[n]); 33 | for(int i=n-1;i>0;i--){ 34 | totalSa[i]=add(totalSa[i+1],sa[i]); 35 | totalSb[i]=add(totalSb[i+1],sb[i]); 36 | totalSaSb[i]=add(totalSaSb[i+1],mul(sa[i],sb[i])); 37 | } 38 | for(int i=1;i<=n;i++){ 39 | long long t1=mul(sb[i-1],totalSa[i]); 40 | long long t2=mul(sa[i-1],totalSb[i]); 41 | long long t3=mul((n-i+1),mul(sa[i-1],sb[i-1])); 42 | ans=(ans+add(totalSaSb[i],t3)+(MOD-add(t1,t2)))%MOD; 43 | } 44 | cout< 2 | using namespace std; 3 | ifstream fin("none62.in"); 4 | ofstream fout("none62.out"); 5 | const int MAXL=7; 6 | int f[MAXL+1][10]; 7 | int a,b; 8 | 9 | void dp(){ 10 | for(int i=0;i<=9;i++) { 11 | if (i==4) f[0][i]=0; 12 | else f[0][i]=1; 13 | } 14 | for(int i=1;i<=MAXL;i++){ 15 | for(int j=0;j<=9;j++){ 16 | if (j==4) f[i][j]=0; 17 | else 18 | for(int k=0;k<=9;k++){ 19 | if (!(j==6&&k==2)) f[i][j]+=f[i-1][k]; 20 | } 21 | } 22 | 23 | } 24 | } 25 | int calc(int x){ 26 | int t[MAXL+1]={0}; 27 | int k=0; 28 | while(x>0){ 29 | int d=x % 10; 30 | t[k]=d; 31 | k++; 32 | x= x / 10; 33 | } 34 | int tot=0,ans=0; 35 | int i=max(k-1,0); 36 | for(;i>=0;i--){ 37 | int d=t[i]; 38 | for(int j=0;j>a>>b; 51 | while(!(a==0&&b==0)){ 52 | int n1=calc(a-1); 53 | int n2=calc(b); 54 | fout<>a>>b; 56 | } 57 | } -------------------------------------------------------------------------------- /[基本算法]宽度优先搜索/area.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using namespace std; 4 | ifstream fin("area.in"); 5 | ofstream fout("area.out"); 6 | 7 | struct Point{ 8 | int x,y; 9 | }; 10 | int dir_off[4][2]={{-1,0},{1,0},{0,-1},{0,1}}; 11 | 12 | const int MAXN=100; 13 | int colors[MAXN][MAXN]; 14 | int n,m; 15 | int ans; 16 | 17 | int bfs(int x,int y){ 18 | if (colors[x][y]==0) return 0; 19 | int c=0; 20 | queue qe; 21 | Point start={x,y}; 22 | qe.push(start); 23 | c++; 24 | colors[x][y]=0; 25 | 26 | while(!qe.empty()){ 27 | Point cur=qe.front(); 28 | for(int d=0;d<4;d++){ 29 | int newx=cur.x+dir_off[d][0]; 30 | int newy=cur.y+dir_off[d][1]; 31 | if (newx<0||newx>=n||newy<0||newy>=m) continue; 32 | if (colors[newx][newy]==1){ 33 | Point next={newx,newy}; 34 | qe.push(next); 35 | c++; 36 | colors[newx][newy]=0; 37 | } 38 | } 39 | qe.pop(); 40 | } 41 | return c; 42 | } 43 | int main(){ 44 | fin>>n>>m; 45 | for(int i=0;i>colors[i][j]; 47 | 48 | for(int i=0;ians) ans=area; 53 | } 54 | fout< 3 | #include 4 | 5 | using namespace std; 6 | ifstream fin("test.in"); 7 | ofstream fout("test.out"); 8 | const int MAXL=10; 9 | const int MAXN=100; 10 | int f[MAXL+1][10][MAXN]; 11 | int a,b,n; 12 | void dp(){ 13 | for(int i=0;i<=9;i++){ 14 | f[0][i][i%n]=1; 15 | } 16 | for(int i=1;i<=MAXL;i++){ 17 | for(int j=0;j<=9;j++){ 18 | for(int k=0;k<=9;k++){ 19 | for(int r=0;r 0) { 29 | int d = x % 10; 30 | t[k] = d; 31 | k++; 32 | x = x / 10; 33 | } 34 | int ans=0,tot=0; 35 | int i = max(k - 1, 0); 36 | for (; i >= 0; i--) { 37 | int d = t[i]; 38 | for(int j=0;j>a>>b>>n){ 49 | memset(f,0,sizeof(f)); 50 | dp(); 51 | int n1=calc(a-1); 52 | int n2=calc(b); 53 | fout< 2 | #include 3 | using namespace std; 4 | ifstream fin("getnum.in"); 5 | ofstream fout("getnum.out"); 6 | const int MAXN=10; 7 | int n; 8 | int dp[MAXN*2][MAXN][MAXN]; 9 | int cell[MAXN][MAXN]; 10 | 11 | int main(){ 12 | fin>>n; 13 | int a,b,c; 14 | 15 | fin>>a>>b>>c; 16 | while(a>0&&b>0){ 17 | cell[a-1][b-1]=c; 18 | fin>>a>>b>>c; 19 | } 20 | 21 | for(int d=1;d<2*n-1;d++) 22 | for(int i1=0;i1<=min(d,n-1);i1++) 23 | for(int i2=0;i2<=min(d,n-1);i2++){ 24 | int j1=d-i1; 25 | int j2=d-i2; 26 | if (i1==i2){ 27 | if (i1-1>=0) 28 | dp[d][i1][i1]=dp[d-1][i1-1][i1]+cell[i1][j1]; 29 | }else { 30 | if (i1-1>=0&&i2-1>=0) 31 | dp[d][i1][i2]=max(dp[d-1][i1-1][i2-1]+cell[i1][j1]+cell[i2][j2],dp[d][i1][i2]); 32 | if (i2-1>=0) 33 | dp[d][i1][i2]=max(dp[d-1][i1][i2-1]+cell[i1][j1]+cell[i2][j2],dp[d][i1][i2]); 34 | if (i1-1>=0) 35 | dp[d][i1][i2]=max(dp[d-1][i1-1][i2]+cell[i1][j1]+cell[i2][j2],dp[d][i1][i2]); 36 | dp[d][i1][i2]=max(dp[d-1][i1][i2]+cell[i1][j1]+cell[i2][j2],dp[d][i1][i2]); 37 | } 38 | } 39 | fout< 2 | #include 3 | 4 | using namespace std; 5 | const int MAXN=9; 6 | const int MAXK=MAXN*MAXN; 7 | const int MAXS=511;//2^9-1 8 | long long dp[MAXN+1][MAXK+1][MAXS+1]; 9 | int n,k; 10 | bool can(int s){ 11 | if (s&(s>>1)) return false; 12 | return true; 13 | } 14 | bool conflict(int s1,int s2){ 15 | if (s1&s2) return true; 16 | else if ((s1>>1)&s2) return true; 17 | else if ((s1<<1)&s2) return true; 18 | else return false; 19 | } 20 | int num[MAXS+1]; 21 | 22 | int lastS; 23 | int main(){ 24 | cin>>n>>k; 25 | lastS=pow(2,n)-1; 26 | for(int s=0;s<=lastS;s++){ 27 | int st=s; 28 | while(st>0){ 29 | num[s]+=st&1; 30 | st=st>>1; 31 | } 32 | } 33 | 34 | dp[0][0][0]=1; 35 | for(int i=1;i<=n;i++){ 36 | for(int j=0;j<=k;j++){ 37 | if (j>n*i) break; 38 | for(int s1=0;s1<=lastS;s1++){ 39 | if (!can(s1)) continue; 40 | for(int s2=0;s2<=lastS;s2++){ 41 | if (!can(s2)) continue; 42 | if (!conflict(s1,s2)&&(j-num[s1]>=0)){ 43 | dp[i][j][s1]+=dp[i-1][j-num[s1]][s2]; 44 | } 45 | } 46 | } 47 | } 48 | } 49 | long long ans=0; 50 | for(int s=0;s<=lastS;s++) ans+=dp[n][k][s]; 51 | cout< 3 | #include 4 | #include 5 | #include 6 | 7 | using namespace std; 8 | ifstream fin("leaf.in"); 9 | ofstream fout("leaf.out"); 10 | 11 | const int MAXM=10000; 12 | const int INF=0x7fffffff; 13 | int m,n; 14 | int color[MAXM+1]; 15 | vector tree[MAXM+1]; 16 | int dp_min[MAXM+1][2];//dp_min[i][j]表示以i为根的子树中,根结点i着色j时最少的着色点数 17 | bool visited[MAXM+1]; 18 | 19 | void dp(int i){ 20 | visited[i]=true; 21 | if (color[i]>-1) return; 22 | int s=tree[i].size(); 23 | int s0=0,s1=0; 24 | for(int k=0;k>m>>n; 38 | memset(color,-1,sizeof(color)); 39 | for(int i=1;i<=n;i++) { 40 | fin>>color[i]; 41 | dp_min[i][color[i]]=1; 42 | dp_min[i][1-color[i]]=INF; 43 | } 44 | for(int i=0;i>a>>b; 47 | tree[a].push_back(b); 48 | tree[b].push_back(a); 49 | } 50 | memset(visited,false,sizeof(visited)); 51 | dp(n+1); 52 | int ans=min(dp_min[n+1][0],dp_min[n+1][1]); 53 | fout< 2 | #include 3 | #include 4 | #define ll long long 5 | using namespace std; 6 | const int MAXN=1000000000; 7 | const int MAXK=50011; 8 | const int MOD=998244353; 9 | map id; 10 | ll dp[2][MAXK*2]; 11 | ll dp_sum[2]; 12 | int n,m,k; 13 | vector G[MAXK*2]; 14 | 15 | int main(){ 16 | cin>>n>>m>>k; 17 | id[1]=1; 18 | int cnt=1; 19 | for(int i=0;i>a>>b; 22 | if (a!=b){ 23 | //为有限制的点编个新号,在新号上建邻接表 24 | if (id.find(a)==id.end()) id[a]=++cnt; 25 | if (id.find(b)==id.end()) id[b]=++cnt; 26 | G[id[b]].push_back(id[a]); 27 | } 28 | } 29 | //dp[cur][cnt+1]存放本轮中到达没有限制的那些点的方案数总和 30 | dp[0][1]=1; 31 | dp_sum[0]=1; 32 | int cur=1; 33 | for(int j=1;j<=m;j++){ 34 | dp_sum[cur]=0; 35 | for(int i=1;i<=cnt;i++){ 36 | dp[cur][i]=(dp_sum[!cur]+MOD-dp[!cur][i]) % MOD; 37 | for(int k=0;k 2 | #include 3 | 4 | using namespace std; 5 | const int MAXN=20; 6 | const int MAXS=MAXN*100; 7 | int a[MAXN+1]; 8 | int n,m; 9 | bool removed[MAXN+1]; 10 | bool can[MAXS+1]; 11 | int maxtotal; 12 | void calc(){ 13 | memset(can,false,sizeof(can)); 14 | can[0]=true; 15 | int sum=0; 16 | int total=0; 17 | for(int i=1;i<=n;i++){ 18 | if (!removed[i]){ 19 | sum+=a[i]; 20 | for(int j=sum;j>=a[i];j--) //此循环要从大到小枚举,否则a[i]就会被多次使用。这是一个背包问题 21 | if (!can[j]&&can[j-a[i]]){ 22 | can[j]=true; 23 | total++; 24 | } 25 | } 26 | /*上面这部分也可以这样写 27 | if (!removed[i]){ 28 | for(int j=sum;j>=0;j--) 29 | if (can[j]&&!can[j+a[i]]){ 30 | can[j+a[i]]=true; 31 | total++; 32 | } 33 | sum+=a[i]; 34 | }*/ 35 | } 36 | maxtotal=max(maxtotal,total); 37 | } 38 | void dfs(int start,int num){ 39 | if (num==0){ 40 | calc(); 41 | }else { 42 | for(int i=start;i<=n-(num-1);i++){ 43 | removed[i]=true; 44 | dfs(i+1,num-1); 45 | removed[i]=false; 46 | } 47 | } 48 | } 49 | int main(){ 50 | cin>>n>>m; 51 | for(int i=1;i<=n;i++) { 52 | cin>>a[i]; 53 | } 54 | dfs(1,m); 55 | cout< 2 | #include 3 | #include 4 | #include 5 | 6 | using namespace std; 7 | const int MAXN=100000; 8 | const int INF=0x3fffffff; 9 | 10 | struct Edge{ 11 | int v,w; 12 | }; 13 | vector G[MAXN+1]; 14 | int dist[MAXN+1]; 15 | struct Node{ 16 | int u; 17 | bool operator<(const Node other)const{ 18 | return dist[u]>dist[other.u]; 19 | } 20 | }; 21 | priority_queue pri_qu; 22 | bool in_queue[MAXN+1]; 23 | 24 | int n,m,s; 25 | void dijkstra(int s){ 26 | for(int i=1;i<=n;i++) dist[i]=INF; 27 | dist[s]=0; 28 | pri_qu.push({s}); 29 | in_queue[s]=true; 30 | while(!pri_qu.empty()){ 31 | int u=pri_qu.top().u; 32 | pri_qu.pop(); 33 | in_queue[u]=false; 34 | for(int k=0;k 2 | #include 3 | using namespace std; 4 | const int MAXN=200000; 5 | int a[MAXN+10],u[MAXN+10]; 6 | int n,m; 7 | priority_queue maxheap; 8 | priority_queue,greater > minheap; 9 | 10 | int main(){ 11 | cin>>m>>n; 12 | for(int i=0;i>a[i]; 13 | for(int i=0;i>u[i]; 14 | 15 | int maxheap_cursize=0; 16 | int maxheap_limitsize=0; 17 | int uindex=0; 18 | for(int i=0;i=minheap.top()) minheap.push(a[i]); 23 | else { 24 | if (maxheap_cursize 2 | #include 3 | #include 4 | using namespace std; 5 | const int MAXT=100; 6 | const int MAXINT=1000000000; 7 | struct Edge{ 8 | int v,w; 9 | }; 10 | vector G[MAXT+10]; 11 | int dist[2][MAXT+10]; 12 | map id; 13 | int N,T,S,E; 14 | int main(){ 15 | cin>>N>>T>>S>>E; 16 | int cnt=1; 17 | id[S]=cnt++; 18 | id[E]=cnt++; 19 | 20 | for(int i=0;i>w>>u>>v; 23 | if (id.find(u)==id.end()) id[u]=cnt++; 24 | if (id.find(v)==id.end()) id[v]=cnt++; 25 | G[id[u]].push_back({id[v],w}); 26 | G[id[v]].push_back({id[u],w}); 27 | } 28 | for(int i=1;i<=cnt;i++){ 29 | dist[0][i]=MAXINT; 30 | dist[1][i]=MAXINT; 31 | } 32 | int u=id[S]; 33 | for(int k=0;k 3 | #include 4 | 5 | using namespace std; 6 | ifstream fin("cowfood.in"); 7 | ofstream fout("cowfood.out"); 8 | const int MAXN = 12; 9 | const int MAXS = 4096; 10 | int m, n; 11 | int flag[MAXN + 1]; 12 | long long dp[MAXN + 1][MAXS + 1];//dp[i][s]表示前i行中,第i行的状态为s时的方案数 13 | vector states; 14 | long long ans; 15 | 16 | int main() { 17 | fin >> m >> n; 18 | for (int i = 1; i <= m; i++) { 19 | for (int j = 0; j < n; j++) { 20 | int a; 21 | fin >> a; 22 | flag[i] = (flag[i] << 1) + a; 23 | } 24 | } 25 | 26 | for (int s = 0; s <= (2 << n) - 1; s++) { 27 | if (s&(s<<1)) continue; 28 | states.push_back(s); 29 | } 30 | int count = states.size(); 31 | //dp 32 | dp[0][0] = 1; 33 | for (int i = 1; i <= m; i++) { 34 | for (int i1 = 0; i1 < count; i1++) { 35 | int s1 = states[i1]; 36 | if (((~flag[i]) & s1) > 0) 37 | continue; 38 | for (int i2 = 0; i2 < count; i2++) { 39 | int s2 = states[i2]; 40 | if ((s1 & s2) > 0) continue; 41 | dp[i][s1] = (dp[i][s1]+dp[i - 1][s2]) % 100000000; 42 | } 43 | } 44 | } 45 | //output 46 | 47 | for (int i = 0; i < count; i++) { 48 | int s = states[i]; 49 | ans =(ans+ dp[m][s]) % 100000000; 50 | } 51 | fout << ans; 52 | } -------------------------------------------------------------------------------- /[提高训练]动态规划之树型DP/guard.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using namespace std; 4 | ifstream fin("guard.in"); 5 | ofstream fout("guard.out"); 6 | 7 | const int MAXN=1500; 8 | const int INF=0x7fffffff; 9 | vector graph[MAXN+1]; 10 | int cost[MAXN+1]; 11 | int dp_min[MAXN+1][3];//dp_min[i][j] j=0表示不驻守可不观察根结点i j=1表示不驻守必须可观察根结点i j=2表示驻守必然可观赛根结点i 12 | int n; 13 | 14 | void dp(int x){ 15 | int size=graph[x].size(); 16 | int s2=0,s0=0; 17 | int min_deta=INF; 18 | for(int k=0;k>n; 34 | int root; 35 | bool first=true; 36 | for(int i=0;i>x>>c>>m; 39 | if (first){ 40 | root=x; 41 | first=false; 42 | } 43 | cost[x]=c; 44 | for(int k=0;k>y; 47 | graph[x].push_back(y); 48 | } 49 | } 50 | dp(root); 51 | fout< 2 | #include 3 | #include 4 | 5 | using namespace std; 6 | const int MAXN=500000; 7 | char node[MAXN+1]; 8 | vector tree[MAXN+1]; 9 | int n; 10 | stack st; 11 | long long sum[MAXN+1];//sum[i]表示从1到i节点的路径中总的合法子串数 12 | long long lst[MAXN+1];//lst[i]表示从1到i节点的路径中i节点带来的合法子串数 13 | int parent[MAXN+1]; 14 | void dfs(int u){ 15 | int flag; 16 | int top; 17 | if (node[u]=='('||st.empty()){ 18 | flag=1; 19 | lst[u]=0; 20 | st.push(u); 21 | }else { 22 | top=st.top(); 23 | if (node[top]=='('){//有匹配的时候 24 | flag=2; 25 | st.pop(); 26 | lst[u]=lst[parent[top]]+1;//当前结点与top匹配,它的带来的合法子串为 27 | //top的父结点带来的合法子串数加1 28 | }else { 29 | flag=1; 30 | lst[u]=0; 31 | st.push(u); 32 | } 33 | } 34 | sum[u]=sum[parent[u]]+lst[u]; 35 | //计算子结点 36 | for(int k=0;k>n; 50 | for(int i=1;i<=n;i++) cin>>node[i]; 51 | for(int i=1;i>p; 54 | tree[p].push_back(i+1); 55 | } 56 | dfs(1); 57 | long long ans=1*sum[1]; 58 | for(int i=2;i<=n;i++) ans=ans xor (i*sum[i]); 59 | cout< 3 | using namespace std; 4 | ifstream fin("merge.in"); 5 | ofstream fout("merge.out"); 6 | const int MAXN=200; 7 | int stones[MAXN*2]; 8 | int totalStones[MAXN*2][MAXN]; 9 | int dp_min[MAXN*2][MAXN+1];//dp_min[i][j]表示以第i颗石子为起始,长度为j的区间(即[i,i+j-1])里的石子合并成一堆所能得到的最小得分 10 | int dp_max[MAXN*2][MAXN+1];//同上类推 11 | int n; 12 | int main(){ 13 | fin>>n; 14 | for(int i=0;i>stones[i]; 16 | stones[i+n]=stones[i]; 17 | } 18 | int m=n*2-1; 19 | for(int i=0;ilastMax) lastMax=dp_max[i][n]; 41 | } 42 | fout< 2 | #include 3 | using namespace std; 4 | 5 | ifstream fin("apple.in"); 6 | ofstream fout("apple.out"); 7 | const int MAXN=100; 8 | int lc[MAXN+1]; 9 | int rc[MAXN+1]; 10 | int lw[MAXN+1]; 11 | int rw[MAXN+1]; 12 | int apple[MAXN+1][MAXN+1]; 13 | int dp_max[MAXN+1][MAXN+1]; 14 | 15 | int n,q; 16 | 17 | void build_tree(int i){ 18 | for(int j=1;j<=n;j++){ 19 | if (apple[i][j]>=0){ 20 | if (lc[i]==0){ 21 | lc[i]=j; 22 | lw[i]=apple[i][j]; 23 | }else { 24 | rc[i]=j; 25 | rw[i]=apple[i][j]; 26 | } 27 | apple[i][j]=-1; 28 | apple[j][i]=-1; 29 | build_tree(j); 30 | } 31 | } 32 | } 33 | void dp(int i){ 34 | if (lc[i]>0) dp(lc[i]); 35 | if (rc[i]>0) dp(rc[i]); 36 | for(int j=1;j<=q;j++){ 37 | dp_max[i][j]=dp_max[lc[i]][j-1]+lw[i];//无右子树 38 | dp_max[i][j]=max(dp_max[i][j],dp_max[rc[i]][j-1]+rw[i]);//无左子树 39 | if (j>=2){ 40 | for(int k=0;k<=j-2;k++){ 41 | dp_max[i][j]=max(dp_max[i][j],dp_max[lc[i]][k]+dp_max[rc[i]][j-k-2]+lw[i]+rw[i]); 42 | } 43 | } 44 | } 45 | } 46 | int main(){ 47 | fin>>n>>q; 48 | memset(apple,-1,sizeof(apple)); 49 | for(int i=1;i<=n-1;i++){ 50 | int a,b,c; 51 | fin>>a>>b>>c; 52 | apple[a][b]=c; 53 | apple[b][a]=c; 54 | } 55 | build_tree(1); 56 | dp(1); 57 | fout< 2 | #include 3 | #define ll long long 4 | using namespace std; 5 | const int MAXN=20; 6 | const int MAXM=1200000; 7 | struct Node{ 8 | ll val; 9 | int flag; 10 | bool operator <(const Node other)const{ 11 | return valsum/2) return; 24 | if (flag>0) search_results[search_count++]={val,flag}; 25 | for(int i=pos+1;i<=n;i++){ 26 | dfs(i,val+number[i],flag+(1<<(i-1))); 27 | } 28 | } 29 | 30 | int main(){ 31 | cin>>n; 32 | for(int i=1;i<=n;i++) { 33 | cin>>number[i]; 34 | sum+=number[i]; 35 | } 36 | dfs(0,0,0); 37 | sort(search_results,search_results+search_count); 38 | int startPos=0; 39 | ll curVal=search_results[0].val; 40 | for(int i=1;i 3 | #include 4 | 5 | using namespace std; 6 | ifstream fin("windy.in"); 7 | ofstream fout("windy.out"); 8 | 9 | const int MAXLEVEL=31; 10 | int f[MAXLEVEL+1][11];//f[i][j] 表示高度为i的完全10叉树中当根结点为j时, 11 | //由根结点到叶结点的路径所组成的数是windy数的个数, 12 | //其中当j=10时表示先导为0的情形 13 | //而当j=0时,0不作为先导0,要与后面的数位作比较 14 | int a,b; 15 | void dp(){ 16 | for(int i=0;i<=9;i++) f[0][i]=1; 17 | f[0][10]=1; 18 | for(int i=1;i<=MAXLEVEL;i++){ 19 | for(int j=0;j<=9;j++) 20 | for(int k=0;k<=9;k++){ 21 | if (abs(j-k)>=2) f[i][j]+=f[i-1][k]; 22 | } 23 | for(int k=1;k<=10;k++) f[i][10]+=f[i-1][k]; 24 | } 25 | } 26 | int calc(int x){ 27 | int t[MAXLEVEL+1]={0}; 28 | int k=0; 29 | while(x>0){ 30 | int d=x % 10; 31 | t[k]=d; 32 | k++; 33 | x= x / 10; 34 | } 35 | int tot=-2,ans=0; 36 | int i=max(k-1,0); 37 | for(;i>=0;i--){ 38 | int d=t[i]; 39 | if (d>0){ 40 | if (tot==-2) ans+=f[i][10];//当计算最高位的时候,要加上先导为0的情形 41 | else if (abs(0-tot)>=2) ans+=f[i][0];//非最高位的时候要看0与前一位是否满足要求 42 | } 43 | for(int j=1;j=2) ans+=f[i][j]; 45 | } 46 | 47 | if (abs(d-tot)<2) break; 48 | if (i==0) ans++; 49 | tot=d; 50 | } 51 | return ans; 52 | } 53 | int main(){ 54 | fin>>a>>b; 55 | dp(); 56 | int n1=calc(a-1); 57 | int n2=calc(b); 58 | fout< 3 | using namespace std; 4 | ifstream fin("data.in"); 5 | ofstream fout("data.out"); 6 | 7 | const int MAXLEVEL=31; 8 | 9 | int f[MAXLEVEL+1][MAXLEVEL+1];//f[i][j]表示高度为i的完全二叉树中当根结点为0时, 10 | //从根结点到叶结点的路径中含有1的个数为j的叶结点数量 11 | int x,y,k,b; 12 | // 13 | void dp(){ 14 | f[0][0]=1; 15 | for(int i=1;i<=MAXLEVEL;i++){ 16 | f[i][0]=f[i-1][0]; 17 | for(int j=1;j<=i;j++) f[i][j]=f[i-1][j]+f[i-1][j-1]; 18 | } 19 | } 20 | //计算小于等x内的正整数内,正好等于K个互不相同的2的幂之和的数的个数 21 | int calc(int x,int k){ 22 | int tot=0,ans=0; 23 | for(int i=31;i>=0;i--) 24 | { 25 | if (x&(1<k) break; 30 | } 31 | } 32 | if (tot==k&&x==0) ans++; 33 | return ans; 34 | } 35 | //将非2进制数,转换成二进制去处理。对于b进制数从高位检查,当此位数大于1时,则后面的全改为1 36 | int trans(int x,int b){ 37 | int t[32]={0}; 38 | int k=0; 39 | while(x>0){ 40 | int d=x % b; 41 | t[k]=d; 42 | k++; 43 | x= x / b; 44 | } 45 | int over1=false; 46 | int ret=0; 47 | for(int i=k-1;i>=0;i--){ 48 | if (t[i]>1) over1=true; 49 | if (over1) t[i]=1; 50 | ret=(ret<<1)+t[i]; 51 | } 52 | return ret; 53 | } 54 | int main(){ 55 | fin>>x>>y; 56 | fin>>k>>b; 57 | x=x-1; 58 | if (b>2){ 59 | x=trans(x,b); 60 | y=trans(y,b); 61 | } 62 | dp(); 63 | int n1=calc(x,k); 64 | int n2=calc(y,k); 65 | fout< 3 | using namespace std; 4 | ifstream fin("pebble.in"); 5 | ofstream fout("pebble.out"); 6 | 7 | const int MAXN=100; 8 | int stones[MAXN*2]; 9 | int totalstones[MAXN*2][MAXN]; 10 | int minscore[MAXN*2][MAXN]; 11 | int maxscore[MAXN*2][MAXN]; 12 | int lastminscore; 13 | int lastmaxscore; 14 | 15 | int n; 16 | int main(){ 17 | fin>>n; 18 | for(int i=0;i>stones[i]; 19 | int m=n*2-1; 20 | for(int i=n;ilastmaxscore) lastmaxscore=maxscore[i][n]; 42 | } 43 | fout< 2 | #include 3 | 4 | using namespace std; 5 | const int MAXN=300000; 6 | int a[MAXN+1],b[MAXN+1]; 7 | int n,m; 8 | struct Edge{ 9 | int weight; 10 | char flag; 11 | bool operator <(const Edge other) const{ 12 | return weight>n>>m; 23 | int k=0; 24 | for(int i=1;i<=n;i++) { 25 | cin>>a[i]; 26 | edges[k]={a[i],'h'}; 27 | k++; 28 | } 29 | for(int j=1;j<=m;j++) { 30 | cin>>b[j]; 31 | edges[k]={b[j],'v'}; 32 | k++; 33 | } 34 | sort(edges,edges+n+m); 35 | for(int k=0;k 2 | #include 3 | #include 4 | 5 | using namespace std; 6 | const int MAXN=100; 7 | const double INF=100000000; 8 | const double e=0.0000001; 9 | int n,m; 10 | int v[MAXN+1],w[MAXN+1]; 11 | vector G[MAXN+1]; 12 | double ans; 13 | double dp_f[MAXN+1][MAXN+1]; 14 | int sz[MAXN+1]; 15 | 16 | 17 | void tree_dp(int u,int fa){ 18 | sz[u]=1; 19 | dp_f[u][0]=0; 20 | for(int k=0;k0;i--) 26 | for(int j=0;j<=min(i,sz[v]);j++) dp_f[u][i]=max(dp_f[u][i],dp_f[u][i-j]+dp_f[v][j]); 27 | } 28 | } 29 | for(int i=sz[u];i>=1;i--) dp_f[u][i]=dp_f[u][i-1]+(double)v[u]-ans*(double)w[u]; 30 | } 31 | int main(){ 32 | cin>>n>>m; 33 | for(int i=1;i<=n;i++) cin>>v[i]; 34 | for(int i=1;i<=n;i++) cin>>w[i]; 35 | for(int i=1;i>a>>b; 38 | G[a].push_back(b); 39 | G[b].push_back(a); 40 | } 41 | double left=0.0; 42 | double right=10000; 43 | 44 | while(right-left>e){ 45 | ans=(left+right)/2.0; 46 | for(int i=1;i<=n;i++) 47 | for(int j=0;j<=n;j++) { 48 | dp_f[i][j]=-1*INF; 49 | sz[i]=0; 50 | } 51 | tree_dp(1,0); 52 | double f=-1*INF; 53 | for(int i=1;i<=n;i++) 54 | f=max(f,dp_f[i][n-m]); 55 | if (f>e) left=ans; 56 | else right=ans; 57 | } 58 | cout< 2 | #include 3 | #include 4 | 5 | using namespace std; 6 | const int MAXN=1000; 7 | const int MAXV=20000; 8 | int n; 9 | int high[MAXV+1]; 10 | int gcIndex[MAXN][MAXV*2]; 11 | vector solutions[MAXN]; 12 | vector gc[MAXN]; 13 | 14 | int main(){ 15 | cin>>n; 16 | for(int i=0;i>high[i]; 18 | } 19 | memset(gcIndex,-1,sizeof(gcIndex)); 20 | for(int i=1;i=0) solutions[i][gcIndex[i][curGc]]=(solutions[i][gcIndex[i][curGc]]+newSolutions)% 998244353; 27 | else { 28 | gcIndex[i][curGc]=gc[i].size(); 29 | gc[i].push_back(curGc); 30 | solutions[i].push_back(newSolutions); 31 | } 32 | } 33 | } 34 | int curGc=high[i]-high[k]; 35 | if (gcIndex[i][curGc]>=0) solutions[i][gcIndex[i][curGc]]=(solutions[i][gcIndex[i][curGc]]+1)% 998244353; 36 | else { 37 | gcIndex[i][curGc]=gc[i].size(); 38 | gc[i].push_back(curGc); 39 | solutions[i].push_back(1); 40 | } 41 | } 42 | } 43 | int ans=n; 44 | for(int i=0;i 2 | #include 3 | #include 4 | #include 5 | 6 | using namespace std; 7 | const int MAXN=1000; 8 | const int INF=0x3fffffff; 9 | int n,m; 10 | int dist[MAXN+1]; 11 | int dist1[MAXN+1]; 12 | struct Edge{ 13 | int v,w; 14 | }; 15 | vector G[MAXN+1],G1[MAXN+1]; 16 | queue qu; 17 | //正向图上spfa() 18 | void spfa(int root){ 19 | for(int i=1;i<=n;i++) dist[i]=INF; 20 | dist[1]=0; 21 | qu.push(root); 22 | while(!qu.empty()){ 23 | int u=qu.front(); 24 | qu.pop(); 25 | for(int k=0;k 2 | #include 3 | #include 4 | 5 | using namespace std; 6 | ifstream fin("horse.in"); 7 | ofstream fout("horse.out"); 8 | 9 | const int MAXN=10; 10 | const int MAXS=1023; 11 | long long dp[MAXN+1][MAXN*MAXN+1][MAXS+1];//dp[i][j][s]前i行格子放置j个国王最后一行(即第i行)状态为s时的方案数 12 | int num1[MAXS+1];//保存可行状态中1的个数 13 | vector states;//保存一行内可行的状态,将不可行的状态去掉了,这就是状态压缩 14 | 15 | int n,k; 16 | long long ans; 17 | int check_count(int s) { 18 | if (s&(s<<1)) return -1; 19 | int k=0; 20 | while(s>0){ 21 | k+=(s&1); 22 | s=s>>1; 23 | } 24 | return k; 25 | } 26 | 27 | int main(){ 28 | fin>>n>>k; 29 | //将可行状态保存,并记录对应状态1的个数 30 | for(int state=0;state<=(1 << n) - 1;state++) { 31 | int t=check_count(state); 32 | if (t>=0) { 33 | states.push_back(state); 34 | num1[state]=t; 35 | } 36 | } 37 | int statecount=states.size(); 38 | //进行动规 39 | for(int i=0;i<=n;i++) dp[i][0][0]=1; 40 | for(int i=1;i<=n;i++){ 41 | for(int w=1;w<=k;w++){ 42 | if (w>n*i) break; 43 | for(int i1=0;i1>1&s2)||(s1<<1&s2)) continue;//上下两行状态是否可行 48 | int u=num1[s1]; 49 | if (u<=w) { 50 | dp[i][w][s1]+=dp[i-1][w-u][s2]; 51 | } 52 | } 53 | } 54 | } 55 | //统计最终答案 56 | ans=0; 57 | for(int i=0;i 3 | #include 4 | using namespace std; 5 | ifstream fin("knight.in"); 6 | ofstream fout("knight.out"); 7 | 8 | const int MAXN=1000000; 9 | int fight[MAXN+1]; 10 | long long dp_max[MAXN+1][2][2];//dp_max[u][i][j] 表示结点u的子树的选出的最大战力, 11 | //其中i=0表示子树中的结点不与根结点冲突,i=1表示子树中的结点可能与根结点冲突 12 | //j=0表示当前结点u不被选中,j=1表示当前结点u被选中 13 | bool visited[MAXN+1]; 14 | bool flag[MAXN+1]; 15 | vector graph[MAXN+1]; 16 | int hate[MAXN+1]; 17 | int n; 18 | long long ans; 19 | int root; 20 | void dp(int u){ 21 | visited[u]=true; 22 | int count=graph[u].size(); 23 | long long s00=0,s01=0,s10=0,s11=0; 24 | for(int k=0;k>n; 51 | for(int i=1;i<=n;i++){ 52 | fin>>fight[i]>>hate[i]; 53 | graph[hate[i]].push_back(i); 54 | } 55 | ans=0; 56 | for(int i=1;i<=n;i++){ 57 | if (!visited[i]){ 58 | int r=get_root(i); 59 | root=r; 60 | dp(r); 61 | ans+=max(max(dp_max[r][0][0],dp_max[r][0][1]),dp_max[r][1][0]); 62 | } 63 | } 64 | fout< 2 | #include 3 | #include 4 | 5 | using namespace std; 6 | const int MAXN=3000; 7 | struct Edge{ 8 | int to; 9 | int cost; 10 | }; 11 | vector G[MAXN+1]; 12 | int dp_profit[MAXN+1][MAXN+1];//dp_profit[u][i]表示以u为根结点的子树下,使i个终端用户收看的最大利润 13 | int dp_maxUser[MAXN+1]; 14 | int n,m; 15 | int pay[MAXN+1]; 16 | void dp(int u){ 17 | dp_profit[u][0]=0; 18 | dp_maxUser[u]=0; 19 | if (u>n-m) { 20 | dp_profit[u][1]=pay[u]; 21 | dp_maxUser[u]=1; 22 | } 23 | else { 24 | int s=G[u].size(); 25 | for(int k=0;k0;i--){ 30 | for(int j=1;j<=dp_maxUser[v];j++){ 31 | if (i-j>=0&&i-j<=dp_maxUser[u]) { 32 | dp_profit[u][i]=max(dp_profit[u][i],dp_profit[v][j]+dp_profit[u][i-j]-G[u][k].cost); 33 | } 34 | } 35 | } 36 | dp_maxUser[u]=newMaxUser; 37 | } 38 | } 39 | } 40 | int main(){ 41 | cin>>n>>m; 42 | for(int u=1;u<=n-m;u++){ 43 | int k; 44 | cin>>k; 45 | for(int j=1;j<=k;j++){ 46 | int a,c; 47 | cin>>a>>c; 48 | G[u].push_back({a,c}); 49 | } 50 | } 51 | for(int u=n-m+1;u<=n;u++) cin>>pay[u]; 52 | for(int u=1;u<=n;u++) for(int i=0;i<=m;i++) dp_profit[u][i]=INT_MIN; 53 | dp(1); 54 | int ans=0; 55 | for(int i=m;i>=0;i--) { 56 | if (dp_profit[1][i]>=0) { 57 | ans=i; 58 | break; 59 | } 60 | } 61 | cout< 2 | #include 3 | 4 | using namespace std; 5 | const int MAXN=100; 6 | const int MAXM=2000; 7 | const int MOD=998244353; 8 | int n,m; 9 | int a[MAXN+1][MAXM+1]; 10 | long long sum[MAXN];// 11 | 12 | long long all[MAXN+1];//all[i]表示前i种烹饪方法中符合1、2条件的所有方案数 13 | long long dp[MAXN+1][MAXN+1][MAXN+1]; 14 | 15 | int main(){ 16 | cin>>n>>m; 17 | for(int i=1;i<=n;i++) 18 | for(int j=1;j<=m;j++) { 19 | cin>>a[i][j]; 20 | sum[i]=(sum[i]+a[i][j]) % MOD; 21 | } 22 | all[1]=sum[1]; 23 | for(int i=2;i<=n;i++){ 24 | all[i]=(all[i-1]+(all[i-1]*sum[i])% MOD+sum[i]) % MOD; 25 | } 26 | int t=0; 27 | for(int j=1;j<=m;j++){ 28 | memset(dp,0,sizeof(dp)); 29 | dp[1][1][0]=(sum[1]-a[1][j]+MOD) % MOD; 30 | dp[1][1][1]=a[1][j]; 31 | for(int i=2;i<=n;i++){ 32 | for(int k=1;k<=i;k++){ 33 | for(int p=0;p<=k;p++){ 34 | dp[i][k][p]=dp[i-1][k][p] % MOD; 35 | if (k>1) { 36 | if (p0) dp[i][k][p]=(dp[i][k][p]+(dp[i-1][k-1][p-1]*a[i][j])% MOD)% MOD; 38 | } 39 | if (k==1){ 40 | if (p0) dp[i][k][p]=(dp[i][k][p]+a[i][j])% MOD; 42 | } 43 | } 44 | } 45 | } 46 | for(int k=1;k<=n;k++) 47 | for(int p=k;p>k/2;p--){ 48 | t=(t+dp[n][k][p]) % MOD; 49 | } 50 | } 51 | int ans=(all[n]-t+MOD) % MOD; 52 | cout< 3 | #include 4 | using namespace std; 5 | const int MAXN=100000; 6 | const int MAXJ=20; 7 | int n,q; 8 | vector G[MAXN+1]; 9 | int deep[MAXN+1]; 10 | int f[MAXN+1][MAXJ+1]; 11 | 12 | void pre(int u,int fa){ 13 | deep[u]=deep[fa]+1; 14 | f[u][0]=fa; 15 | for(int k=0;k=0;j--) if (deep[f[x][j]]>=deep[y]) x=f[x][j]; 25 | if (x==y) return x; 26 | for(int j=MAXJ;j>=0;j--) 27 | if (f[x][j]!=f[y][j]){ 28 | x=f[x][j]; 29 | y=f[y][j]; 30 | } 31 | return f[x][0]; 32 | } 33 | int main(){ 34 | cin>>n>>q; 35 | for(int i=1;i>u>>v; 38 | G[u].push_back(v); 39 | G[v].push_back(u); 40 | } 41 | pre(1,0); 42 | 43 | for(int j=1;j<=MAXJ;j++) 44 | for(int u=1;u<=n;u++) 45 | f[u][j]=f[f[u][j-1]][j-1]; 46 | 47 | for(int i=0;i>a>>b>>c>>d; 50 | int ab=lca(a,b); 51 | int cd=lca(c,d); 52 | 53 | int ac=lca(a,c); 54 | int ad=lca(a,d); 55 | int bc=lca(b,c); 56 | int bd=lca(b,d); 57 | //用ab的两个点分别与cd的两个点交叉组合(ac,ac,bc,bd),只要存在一对点的lca均大于或等于ab和cd的lca,则说明两条路径有交点 58 | if((deep[ac]>=deep[ab]&&deep[ac]>=deep[cd]) 59 | ||(deep[ad]>=deep[ab]&&deep[ad]>=deep[cd]) 60 | ||(deep[bc]>=deep[ab]&&deep[bc]>=deep[cd]) 61 | ||(deep[bd]>=deep[ab]&&deep[bd]>=deep[cd])) 62 | cout<<'Y'< 2 | #include 3 | using namespace std; 4 | const int BC=((4713-1)/4+1)+4713*365; 5 | const int RURUI=1582/4+1582*365-31-30-27; 6 | const int YEAR1600=RURUI+78+18*365+5; 7 | const int YEAR2000=YEAR1600+400*365+97; 8 | const int YEARS400=400*365+97; 9 | const int total=BC+YEAR2000+1; 10 | int ping[13]={0,31,28,31,30,31,30,31,31,30,31,30,31}; 11 | int year[total],month[total],day[total]; 12 | int curR,curYear,curMonth,curDay; 13 | int main(){ 14 | curR=0; 15 | curYear=-4713; 16 | bool isRun; 17 | while(curR>q; 44 | for(int i=1;i<=q;i++){ 45 | cin>>r; 46 | int yearinc=0; 47 | if (r>=BC+YEAR2000){ 48 | r-=BC+YEAR1600; 49 | yearinc=(r/YEARS400)*400; 50 | r=r%YEARS400; 51 | r=BC+YEAR1600+r; 52 | } 53 | cout< 2 | #include 3 | #include 4 | #include 5 | 6 | using namespace std; 7 | const int MAXN=10000; 8 | const int INF=1000000001; 9 | int n,m,b; 10 | int f[MAXN+1]; 11 | struct Edge{ 12 | int v,w; 13 | }; 14 | vector G[MAXN+1]; 15 | int minf=INF; 16 | int maxf=0; 17 | bool disabled[MAXN+1]; 18 | int dist[MAXN+1]; 19 | queue qu; 20 | void spfa(int root){ 21 | if (disabled[root]) return; 22 | dist[root]=0; 23 | qu.push(root); 24 | while(!qu.empty()){ 25 | int u=qu.front(); 26 | qu.pop(); 27 | for(int k=0;k>n>>m>>b; 40 | for(int i=1;i<=n;i++) { 41 | cin>>f[i]; 42 | minf=min(minf,f[i]); 43 | maxf=max(maxf,f[i]); 44 | } 45 | for(int k=0;k>a>>b>>c; 48 | G[a].push_back({b,c}); 49 | G[b].push_back({a,c}); 50 | } 51 | int left=minf; 52 | int right=maxf; 53 | while(leftmid) disabled[i]=true; 58 | dist[i]=INF; 59 | } 60 | spfa(1); 61 | if (dist[n]>b){ 62 | left=mid+1; 63 | }else right=mid; 64 | } 65 | memset(disabled,false,sizeof(disabled)); 66 | for(int i=1;i<=n;i++){ 67 | if (f[i]>right) disabled[i]=true; 68 | dist[i]=INF; 69 | } 70 | spfa(1); 71 | if (dist[n]<=b) cout< 2 | #include 3 | 4 | using namespace std; 5 | 6 | struct Set{ 7 | bool flag[26]={false}; 8 | bool has(char c) const { 9 | if (flag[c-'a']) return true; 10 | else return false; 11 | } 12 | void add(char c){ 13 | flag[c-'a']=true; 14 | } 15 | void input(char s[]){ 16 | memset(flag,0,sizeof(flag)); 17 | int len=strlen(s); 18 | for(int i=0;i>n; 59 | for(int i=0;i>str1>>op>>str2; 61 | s1.input(str1); 62 | s2.input(str2); 63 | switch(op){ 64 | case '+': 65 | (s1+s2).output(); 66 | break; 67 | case '-': 68 | (s1-s2).output(); 69 | break; 70 | case '*': 71 | (s1*s2).output(); 72 | break; 73 | } 74 | } 75 | system("pause"); 76 | } -------------------------------------------------------------------------------- /[洛谷题单]线段树与树状数组/P3372.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #define ll long long 3 | using namespace std; 4 | const int MAXN=100000; 5 | ll a[MAXN+1]; 6 | struct Node{ 7 | int l,r; 8 | ll sum; 9 | ll lz; 10 | }; 11 | Node tree[(MAXN+1)*2]; 12 | void build(int i,int l,int r){ 13 | tree[i].l=l; 14 | tree[i].r=r; 15 | if (l==r){ 16 | tree[i].sum=a[l]; 17 | return; 18 | } 19 | int mid=(l+r)/2; 20 | build(i*2,l,mid); 21 | build(i*2+1,mid+1,r); 22 | tree[i].sum=tree[i*2].sum+tree[i*2+1].sum; 23 | } 24 | void push_down(int i) 25 | { 26 | if(tree[i].lz!=0) 27 | { 28 | tree[i*2].lz+=tree[i].lz;//左右儿子分别加上父亲的lz 29 | tree[i*2+1].lz+=tree[i].lz; 30 | tree[i*2].sum+=tree[i].lz*(tree[i*2].r-tree[i*2].l+1);//左右分别求和加起来 31 | tree[i*2+1].sum+=tree[i].lz*(tree[i*2+1].r-tree[i*2+1].l+1); 32 | tree[i].lz=0;//父亲lz归零 33 | } 34 | return ; 35 | } 36 | void add(int i,int l,int r,int k){ 37 | if (tree[i].l>=l&&tree[i].r<=r){ 38 | tree[i].sum+=k*(tree[i].r-tree[i].l+1); 39 | tree[i].lz+=k; 40 | return; 41 | } 42 | push_down(i); 43 | if (tree[i*2].r>=l) add(i*2,l,r,k); 44 | if (tree[i*2+1].l<=r) add(i*2+1,l,r,k); 45 | tree[i].sum=tree[i*2].sum+tree[i*2+1].sum; 46 | } 47 | ll query(int i,int l,int r){ 48 | if (tree[i].l>=l&&tree[i].r<=r) return tree[i].sum; 49 | push_down(i); 50 | ll s=0; 51 | if (tree[i*2].r>=l) s+=query(i*2,l,r); 52 | if (tree[i*2+1].l<=r) s+=query(i*2+1,l,r); 53 | return s; 54 | } 55 | int n,m; 56 | int main(){ 57 | cin>>n>>m; 58 | for(int i=1;i<=n;i++) cin>>a[i]; 59 | build(1,1,n); 60 | for(int i=1;i<=m;i++){ 61 | int o,x,y,k; 62 | cin>>o; 63 | if (o==2){ 64 | cin>>x>>y; 65 | cout<>x>>y>>k; 68 | add(1,x,y,k); 69 | } 70 | } 71 | } -------------------------------------------------------------------------------- /[提高训练]动态规划之状压DP/paint.cpp: -------------------------------------------------------------------------------- 1 | //#1026. 「一本通 5.4 练习 1」涂抹果酱 2 | #include 3 | #include 4 | #include 5 | 6 | using namespace std; 7 | ifstream fin("paint.in"); 8 | ofstream fout("paint.out"); 9 | const int MAXN=10000; 10 | const int MAXS=2000; 11 | int dp[MAXN+1][MAXS]; 12 | vector states; 13 | int n,m; 14 | 15 | bool check(int s){ 16 | int pre=-1; 17 | for(int i=0;i>n>>m; 42 | fin>>k; 43 | for(int i=0;i>a; 46 | flagk=flagk*3+(a-1); 47 | } 48 | mi3[0]=1; 49 | for(int i=1;i<20;i++) mi3[i]=3*mi3[i-1]; 50 | for(int s=0;s<=mi3[m]-1;s++){ 51 | if (check(s)) states.push_back(s); 52 | } 53 | int count=states.size(); 54 | for(int i=0;i 3 | #include 4 | #include 5 | #include 6 | 7 | using namespace std; 8 | ifstream fin("dark_castle.in"); 9 | ofstream fout("dark_castle.out"); 10 | 11 | const int MAXN=1000; 12 | const int INF=0x7fffffff; 13 | struct edge{ 14 | int v; 15 | int w; 16 | }; 17 | vector graph[MAXN+1]; 18 | int d[MAXN+1]; 19 | struct node { 20 | int v; 21 | bool operator<(const node other) const 22 | { 23 | return d[v] > d[other.v]; //小顶堆 24 | } 25 | }; 26 | priority_queue minheap; 27 | int n,m; 28 | long long ans; 29 | void dijikstra(){ 30 | d[1]=0; 31 | minheap.push({1}); 32 | while(!minheap.empty()){ 33 | node cur=minheap.top(); 34 | minheap.pop(); 35 | int u=cur.v; 36 | int s=graph[u].size(); 37 | for(int k=0;k>n>>m; 68 | for(int i=0;i>x>>y>>l; 71 | graph[x].push_back({y,l}); 72 | graph[y].push_back({x,l}); 73 | } 74 | for(int i=1;i<=n;i++) d[i]=INF; 75 | dijikstra(); 76 | solve(); 77 | fout< 2 | #include 3 | using namespace std; 4 | const int MAXN=16; 5 | struct Rec{ 6 | int x1,y1,x2,y2; 7 | int color; 8 | }; 9 | Rec recs[MAXN+1]; 10 | vector G[MAXN+1]; 11 | int n; 12 | int minTimes[1<>(i-1))&1)==1; 15 | } 16 | int main(){ 17 | cin>>n; 18 | for(int i=1;i<=n;i++){ 19 | int x1,y1,x2,y2,color; 20 | cin>>y1>>x1>>y2>>x2>>color; 21 | recs[i]={x1,y1,x2,y2,color}; 22 | } 23 | for(int i=1;i<=n;i++) 24 | for(int j=1;j<=n;j++){ 25 | if (i!=j&&recs[i].y1==recs[j].y2&&recs[i].x2>recs[j].x1){ 26 | G[i].push_back(j); 27 | } 28 | } 29 | int maxState=(1< 2 | #include 3 | #include 4 | 5 | using namespace std; 6 | const int MAXN=150; 7 | const int INF=0x2fffffff; 8 | int n; 9 | struct Coor{ 10 | double x,y; 11 | double dist_to(const Coor other){ 12 | return sqrt((x-other.x)*(x-other.x)+(y-other.y)*(y-other.y)); 13 | } 14 | }; 15 | Coor crs[MAXN+1]; 16 | double dist[MAXN+1][MAXN+1]; 17 | double maxdist[MAXN+1]; 18 | 19 | void floyd(){ 20 | for(int k=1;k<=n;k++) 21 | for(int i=1;i<=n;i++) 22 | for(int j=1;j<=n;j++){ 23 | if (i==k||k==j||j==i) continue; 24 | dist[i][j]=dist[j][i]=min(dist[i][j],dist[i][k]+dist[k][j]); 25 | } 26 | } 27 | double ans=0.0; 28 | int main(){ 29 | cin>>n; 30 | for(int i=1;i<=n;i++){ 31 | int x,y; 32 | cin>>x>>y; 33 | crs[i]={x,y}; 34 | } 35 | for(int i=1;i<=n;i++) 36 | for(int j=1;j<=n;j++){ 37 | char c; 38 | cin>>c; 39 | int flag=c-'0'; 40 | if (flag==1) dist[i][j]=crs[i].dist_to(crs[j]); 41 | else if (i==j) dist[i][j]=0; 42 | else dist[i][j]=INF; 43 | } 44 | floyd(); 45 | ans=INF; 46 | double oldmax=0; 47 | for(int i=1;i<=n;i++) 48 | for(int j=1;j<=n;j++){ 49 | if (dist[i][j]!=INF) { 50 | maxdist[i]=max(maxdist[i],dist[i][j]); 51 | oldmax=max(oldmax,dist[i][j]); 52 | } 53 | } 54 | for(int i=1;i<=n;i++) 55 | for(int j=1;j<=n;j++){ 56 | if (dist[i][j]==INF) { 57 | double newmax=maxdist[i]+maxdist[j]+crs[i].dist_to(crs[j]); 58 | if (newmax>oldmax) ans=min(ans,newmax); 59 | else { 60 | cout< 3 | #include 4 | #include 5 | #include 6 | using namespace std; 7 | ifstream fin("tree.in"); 8 | ofstream fout("tree.out"); 9 | const int MAXN=100000; 10 | struct edge{ 11 | int u,v,w; 12 | bool operator<(const edge other)const{ 13 | return w edges; 17 | //并查集,由于需要枚举集合中的元素,故而要链式实现 18 | struct node{ 19 | int head,next,last,length; 20 | }; 21 | struct union_find_set{ 22 | node ele[MAXN+1]; 23 | void make_set(){ 24 | for(int i=1;i<=MAXN;i++) ele[i]={i,0,i,1}; 25 | } 26 | void union_set(int x,int y){ 27 | int hx=find_set(x); 28 | int hy=find_set(y); 29 | if (hx!=hy){ 30 | if (ele[hx].length>n; 53 | for(int i=1;i>s>>t>>d; 56 | edges.push_back({s,t,d}); 57 | } 58 | sort(edges.begin(),edges.begin()+edges.size()); 59 | ufs.make_set(); 60 | for(int i=0;i 4 | #include 5 | #include 6 | 7 | using namespace std; 8 | const int MAXN=500000; 9 | const int MAXJ=20; 10 | int n,m; 11 | vector G[MAXN+1]; 12 | int d[MAXN+1]; 13 | int f[MAXN+1][MAXJ+1]; 14 | void pre(int u,int fa){ 15 | d[u]=d[fa]+1; 16 | f[u][0]=fa; 17 | for(int k=0;k=0;j--) if (d[f[x][j]]>=d[y]) x=f[x][j]; 27 | if (x==y) return x; 28 | for(int j=MAXJ;j>=0;j--) 29 | if (f[x][j]!=f[y][j]){ 30 | x=f[x][j]; 31 | y=f[y][j]; 32 | } 33 | return f[x][0]; 34 | } 35 | int main(){ 36 | //cin>>n>>m; 37 | scanf("%d %d",&n,&m); 38 | for(int i=1;i>a>>b; 41 | scanf("%d %d",&a,&b); 42 | G[a].push_back(b); 43 | G[b].push_back(a); 44 | } 45 | 46 | pre(1,0); 47 | for(int j=1;j<=MAXJ;j++) 48 | for(int u=1;u<=n;u++) 49 | f[u][j]=f[f[u][j-1]][j-1]; 50 | for(int i=0;i>x>>y>>z; 53 | scanf("%d %d %d",&x,&y,&z); 54 | int w=lca(x,y); 55 | int w1=lca(y,z); 56 | int w2=lca(z,x); 57 | int choose; 58 | int ans=0; 59 | if (d[w]>=d[w1]&&d[w]>=d[w2]) { 60 | choose=w; 61 | ans=d[x]-d[w]+d[y]-d[w]+d[w]-d[w1]+d[z]-d[w1]; 62 | } 63 | else if (d[w1]>=d[w]&&d[w1]>=d[w2]) { 64 | choose=w1; 65 | ans=d[z]-d[w1]+d[y]-d[w1]+d[w1]-d[w]+d[x]-d[w]; 66 | }else { 67 | choose=w2; 68 | ans=d[z]-d[w2]+d[x]-d[w2]+d[w2]-d[w1]+d[y]-d[w1]; 69 | } 70 | //cout< 3 | #include 4 | #include 5 | 6 | using namespace std; 7 | ifstream fin("cannon.in"); 8 | ofstream fout("cannon.out"); 9 | const int MAXN=100; 10 | const int MAXM=10; 11 | const int MAXS=1024; 12 | 13 | int n,m; 14 | int flag[MAXN+1]; 15 | int dp[MAXN+1][MAXS][MAXS]; 16 | vector states; 17 | int num1[MAXS]; 18 | 19 | int check_cout(int s){ 20 | if (s&(s<<1)) return -1; 21 | if (s&(s<<2)) return -1; 22 | int k=0; 23 | while(s>0){ 24 | k+=s&1; 25 | s=s>>1; 26 | } 27 | return k; 28 | } 29 | int main(){ 30 | fin>>n>>m; 31 | for(int i=1;i<=n;i++){ 32 | for(int j=0;j>c; 35 | flag[i]=flag[i]<<1; 36 | if (c=='H') flag[i]+=1; 37 | } 38 | } 39 | for(int s=0;s<=(1<=0) { 42 | num1[s]=t; 43 | //cout< 3 | #include 4 | #include 5 | 6 | using namespace std; 7 | ifstream fin("newstart.in"); 8 | ofstream fout("newstart.out"); 9 | const int MAXN=300; 10 | int v[MAXN+1]; 11 | int n; 12 | long ans; 13 | struct edge{ 14 | int u,v,w; 15 | bool operator<(const edge other)const{ 16 | return w edges; 20 | 21 | int sumw[MAXN+1],minv[MAXN+1]; 22 | struct union_find_set{ 23 | int father[MAXN+1]; 24 | void make_set(){ 25 | for(int i=1;i<=MAXN;i++) father[i]=i; 26 | } 27 | int find_set(int x){ 28 | while(father[x]!=x) x=father[x]; 29 | return x; 30 | } 31 | void union_set(int x,int y){ 32 | int hx=find_set(x); 33 | int hy=find_set(y); 34 | while(father[y]!=y){ 35 | int p=father[y]; 36 | father[y]=hx; 37 | y=p; 38 | } 39 | father[hy]=hx; 40 | } 41 | }; 42 | union_find_set ufs; 43 | 44 | int main(){ 45 | fin>>n; 46 | for(int i=1;i<=n;i++) fin>>v[i]; 47 | 48 | for(int i=1;i<=n;i++) 49 | for(int j=1;j<=n;j++){ 50 | int p; 51 | fin>>p; 52 | if (i!=j){ 53 | edges.push_back({i,j,p}); 54 | } 55 | } 56 | for(int i=1;i<=n;i++){ 57 | sumw[i]=0; 58 | minv[i]=v[i]; 59 | } 60 | sort(edges.begin(),edges.begin()+edges.size()); 61 | ufs.make_set(); 62 | for(int i=0;i 2 | #include 3 | 4 | using namespace std; 5 | struct State{ 6 | char buttons[13]={0};//按钮状态0—3 7 | char actions[20]={0};//动作串 8 | int step; 9 | int dist; 10 | bool operator<(const State other)const{ 11 | return (dist/2+step)>(other.dist/2+other.step); 12 | } 13 | }; 14 | int calc_dist(State s){ 15 | int ret=0; 16 | for(int i=1;i<=12;i++){ 17 | ret+=(4-s.buttons[i])%4; 18 | } 19 | return ret; 20 | } 21 | int gethash(State s){ 22 | int ret=0; 23 | for(int i=1;i<=12;i++){ 24 | int p=(i-1)*2; 25 | ret+=s.buttons[i]*(1< priQueue; 32 | State start; 33 | int main(){ 34 | for(int i=1;i<=12;i++){ 35 | int si; 36 | cin>>si; 37 | start.buttons[i]=si-1; 38 | for(int j=0;j<4;j++) cin>>a[i][j]; 39 | } 40 | start.step=0; 41 | start.dist=calc_dist(start); 42 | int key=gethash(start); 43 | visited[key]=true; 44 | priQueue.push(start); 45 | while(!priQueue.empty()){ 46 | State cur=priQueue.top(); 47 | priQueue.pop(); 48 | if (cur.dist==0){ 49 | cout< 2 | #include 3 | using namespace std; 4 | const int MAXN=10; 5 | const double pi=3.1415926; 6 | struct Point{ 7 | int x,y; 8 | double dis_to(Point other){ 9 | return sqrt((x-other.x)*(x-other.x)+(y-other.y)*(y-other.y)); 10 | } 11 | }; 12 | 13 | Point points[MAXN]; 14 | double dis[MAXN][MAXN]; 15 | double dis_edge[MAXN][4]; 16 | int minx,maxx,miny,maxy; 17 | double maxarea; 18 | double r[MAXN]; 19 | bool used[MAXN]; 20 | int n; 21 | double get_r(int k){ 22 | double minv=dis_edge[k][0]; 23 | for(int i=1;i<4;i++) minv=min(minv,dis_edge[k][i]); 24 | for(int i=0;i=n) { 30 | maxarea=max(maxarea,areasum); 31 | }else { 32 | for(int k=0;k>n; 47 | Point a,b; 48 | cin>>a.x>>a.y; 49 | cin>>b.x>>b.y; 50 | minx=min(a.x,b.x); 51 | maxx=max(a.x,b.x); 52 | miny=min(a.y,b.y); 53 | maxy=max(a.y,b.y); 54 | area_ju=abs(a.x-b.x)*abs(a.y-b.y); 55 | for(int i=0;i>points[i].x>>points[i].y; 57 | dis_edge[i][0]=abs(points[i].x-minx); 58 | dis_edge[i][1]=abs(points[i].x-maxx); 59 | dis_edge[i][2]=abs(points[i].y-miny); 60 | dis_edge[i][3]=abs(points[i].y-maxy); 61 | } 62 | for(int i=0;i 3 | #include 4 | #include 5 | 6 | using namespace std; 7 | const int MAXN=100; 8 | struct Edge{ 9 | int from,to; 10 | }; 11 | Edge edges[MAXN*MAXN]; 12 | vector G[MAXN+1]; 13 | int edgeNum; 14 | int n; 15 | 16 | int ans1,ans2; 17 | int dfn[MAXN+1],low[MAXN+1]; 18 | stack st; 19 | vector GNew[MAXN+1]; 20 | int scc[MAXN+1]; 21 | int sccIndex; 22 | int no; 23 | bool inStack[MAXN+1]; 24 | int rudu[MAXN+1],chudu[MAXN+1]; 25 | 26 | void tarjan(int u){ 27 | dfn[u]=low[u]=++no; 28 | st.push(u); 29 | inStack[u]=true; 30 | for(int k=0;k>n; 53 | for(int u=1;u<=n;u++){ 54 | int v; 55 | do { 56 | cin>>v; 57 | if (v>0) { 58 | G[u].push_back(v); 59 | edges[edgeNum]={u,v}; 60 | edgeNum++; 61 | } 62 | }while(v>0); 63 | } 64 | for(int u=1;u<=n;u++) if (!dfn[u]) tarjan(u); 65 | for(int i=0;i1) cout< 2 | #include 3 | using namespace std; 4 | const int MAXN=1000000; 5 | const int MAXK=64; 6 | unsigned long long a[MAXN+1]; 7 | unsigned long long n,m; 8 | int c,k; 9 | bool has[MAXK+1]; 10 | int conbit; 11 | int qindanbit; 12 | struct Hnum{ 13 | int e[50]={0}; 14 | int s=1; 15 | void set(int x){ 16 | s=0; 17 | while(x>0){ 18 | e[s]=x&1; 19 | x=x>>1; 20 | s++; 21 | } 22 | } 23 | void mult(int k){ 24 | int c=0; 25 | for(int i=0;i0) { 31 | e[s]=c; 32 | s++; 33 | } 34 | } 35 | void sub(Hnum other){ 36 | int l=max(s,other.s); 37 | int c=0; 38 | for(int i=0;i=0;i--) printf("%d",e[i]); 48 | } 49 | }; 50 | Hnum mi2; 51 | Hnum hn; 52 | int main(){ 53 | scanf("%d %d %d %d",&n,&m,&c,&k); 54 | for(int i=1;i<=n;i++) scanf("%lld",&a[i]); 55 | for(int i=1;i<=m;i++){ 56 | int p,q; 57 | scanf("%d %d",&p,&q); 58 | if (!has[p]){ 59 | conbit++; 60 | has[p]=true; 61 | } 62 | } 63 | unsigned long long total=0; 64 | for(int i=1;i<=n;i++) total|=a[i]; 65 | int i=0; 66 | while(i>i)&1; 68 | if (flag==1&&has[i]) qindanbit++; 69 | i++; 70 | } 71 | int bitinc=conbit-qindanbit; 72 | if (k-bitinc>=64){ 73 | mi2.set(1); 74 | for(int i=1;i<=k-bitinc;i++) mi2.mult(2); 75 | hn.set(n); 76 | mi2.sub(hn); 77 | mi2.output(); 78 | }else { 79 | unsigned long long x=1; 80 | unsigned long long sum=(x<<(k-bitinc)); 81 | unsigned long long ans=sum-n; 82 | printf("%llu",ans); 83 | } 84 | } -------------------------------------------------------------------------------- /[洛谷题单]图论之连通性问题/P3387.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace std; 6 | const int MAXN=10000; 7 | const int MAXM=100000; 8 | 9 | struct Edge{ 10 | int u,v; 11 | }; 12 | Edge edges[MAXM]; 13 | int ecount; 14 | 15 | int w[MAXN+1]; 16 | vector G[MAXN+1],GNew[MAXN+1]; 17 | int n,m; 18 | int no; 19 | int dfn[MAXN+1],low[MAXN+1]; 20 | int sccIndex; 21 | int scc[MAXN+1]; 22 | int sccw[MAXN+1]; 23 | stack st; 24 | bool inStack[MAXN+1]; 25 | 26 | void tarjan(int u){ 27 | dfn[u]=low[u]=++no; 28 | st.push(u); 29 | inStack[u]=true; 30 | for(int k=0;k>n>>m; 65 | for(int i=1;i<=n;i++) cin>>w[i]; 66 | for(int i=1;i<=m;i++){ 67 | int u,v; 68 | cin>>u>>v; 69 | G[u].push_back(v); 70 | edges[ecount++]={u,v}; 71 | } 72 | for(int u=1;u<=n;u++) if (!dfn[u]) tarjan(u); 73 | for(int i=0;i 3 | using namespace std; 4 | ifstream fin("trade.in"); 5 | ofstream fout("trade.out"); 6 | 7 | const int MAXT=2000; 8 | const int MAXP=2000; 9 | const int INF=0x7fffffff; 10 | int ap[MAXT],bp[MAXT],as[MAXT],bs[MAXT]; 11 | int t,p,w; 12 | int dp_max[MAXT][MAXP+1]; 13 | int maxProfit[MAXP+1][MAXT]; 14 | 15 | int main(){ 16 | fin>>t>>p>>w; 17 | if (w==0) w++; 18 | for(int i=0;i>ap[i]>>bp[i]>>as[i]>>bs[i]; 20 | } 21 | //初始化 22 | for(int i=0;ip) break; 40 | dp_max[i][j]=max(dp_max[i][j],0-ap[i]*j); 41 | } 42 | }else { 43 | //处理买 44 | for(int j=1;j<=as[i];j++){ 45 | for(int j1=0;j1<=p;j1++){ 46 | if (maxProfit[j1][last]==-INF) break; 47 | int newj=j1+j; 48 | if (newj>p) break; 49 | dp_max[i][newj]=max(dp_max[i][newj],maxProfit[j1][last]-ap[i]*j); 50 | } 51 | } 52 | //处理卖 53 | for(int j=1;j<=bs[i];j++){ 54 | for(int j1=j;j1<=p;j1++){ 55 | if (maxProfit[j1][last]==-INF) break; 56 | int newj=j1-j; 57 | dp_max[i][newj]=max(dp_max[i][newj],maxProfit[j1][last]+bp[i]*j); 58 | } 59 | } 60 | } 61 | //更新前i天持有j股的最大收益 62 | for(int j=0;j<=p;j++){ 63 | maxProfit[j][i]=max(maxProfit[j][i-1],dp_max[i][j]); 64 | } 65 | } 66 | fout< 2 | #include 3 | #include 4 | #include 5 | #include 6 | const int MAXDIS=20000; 7 | using namespace std; 8 | ifstream fin("track8.in"); 9 | //ofstream fout("track.out"); 10 | struct Edge{ 11 | long to; 12 | int dis; 13 | }; 14 | long n,m; 15 | vector G[50001]; 16 | long sumDis=0; 17 | long minDis=MAXDIS; 18 | long curLenForTrack; 19 | long dp[50001]; 20 | long restMaxLens[50001]; 21 | long parent[50001]; 22 | 23 | long check(vector &lens,long left,long right,long minVal){ 24 | long ret=lens.size(); 25 | while(left<=right){ 26 | long mid=(left+right)/2; 27 | long mid1=mid; 28 | while(mid1>left&&lens[mid1]==0) mid1--; 29 | if (lens[mid1]>=minVal) { 30 | if (mid1 lens; 38 | for(long i=0;i=curLenForTrack) dp[k]++; 46 | else lens.push_back(newRestLen); 47 | } 48 | } 49 | long s=lens.size(); 50 | if (s>0){ 51 | if (s>1) sort(lens.begin(),lens.begin()+s); 52 | for(long i=0;i>n>>m; 66 | for(long i=0;i>a>>b>>c; 70 | Edge e1={b,c}; 71 | G[a].push_back(e1); 72 | Edge e2={a,c}; 73 | G[b].push_back(e2); 74 | sumDis+=c; 75 | if (c circle; 18 | void getPath(int x,int y){ 19 | if (path[x][y]==0) return; 20 | int m=path[x][y]; 21 | cout<>n>>m; 27 | for(int i=1;i<=n;i++) 28 | for(int j=1;j<=n;j++) 29 | if (i!=j) { 30 | w[i][j]=INF; 31 | dist[i][j]=INF; 32 | } 33 | 34 | for(int i=0;i>x>>y>>z; 37 | if (zdist[i][j]+w[j][k]+w[k][i]){ 50 | ans=dist[i][j]+w[j][k]+w[k][i]; 51 | cout< 3 | #include 4 | #include 5 | #include 6 | 7 | using namespace std; 8 | const int MAXN=500; 9 | 10 | ifstream fin("network.in"); 11 | ofstream fout("network.out"); 12 | 13 | struct position{ 14 | int x,y; 15 | double disto(const position other){ 16 | double xdeta=x-other.x; 17 | double ydeta=y-other.y; 18 | return sqrt(xdeta*xdeta+ydeta*ydeta); 19 | } 20 | }; 21 | struct edge{ 22 | int u,v; 23 | double w; 24 | bool operator<(const edge other)const{ 25 | return w edges; 30 | position positions[MAXN+1]; 31 | 32 | struct union_find_set{ 33 | int father[MAXN+1]; 34 | void make_set(){ 35 | for(int i=1;i<=MAXN;i++) father[i]=i; 36 | } 37 | int find_set(int x){ 38 | while(father[x]!=x) x=father[x]; 39 | return x; 40 | } 41 | void union_set(int x,int y){ 42 | int hx=find_set(x); 43 | int hy=find_set(y); 44 | while(father[y]!=y){ 45 | int p=father[y]; 46 | father[y]=hx; 47 | y=p; 48 | } 49 | father[hy]=hx; 50 | } 51 | }; 52 | union_find_set ufs; 53 | 54 | int main(){ 55 | fin>>n>>k; 56 | for(int i=1;i<=n;i++){ 57 | int x,y; 58 | fin>>x>>y; 59 | positions[i]={x,y}; 60 | } 61 | for(int u=1;u<=n;u++) 62 | for(int v=1;v<=n;v++){ 63 | if (u!=v) { 64 | double w=positions[u].disto(positions[v]); 65 | edges.push_back({u,v,w}); 66 | } 67 | } 68 | sort(edges.begin(),edges.begin()+edges.size()); 69 | int m=n-k; 70 | ufs.make_set(); 71 | int c=0; 72 | for(int i=0;i 3 | #include 4 | 5 | using namespace std; 6 | ifstream fin("count.in"); 7 | ofstream fout("count.out"); 8 | 9 | const int MAXL=12; 10 | long long f[MAXL+1][11][10];//f[i][j][d]表示在第i层以j为根的子树中的所有数含数字d的个数 11 | //j=10时表示0为前置0 12 | long long mi10[MAXL]; 13 | long long a,b; 14 | long long ans1[10],ans2[10]; 15 | void dp(){ 16 | for(int i=0;i<=9;i++) f[0][i][i]=1; 17 | f[0][10][0]=1; 18 | for(int i=1;i<=MAXL;i++){ 19 | for(int j=0;j<=9;j++){//当前i层数字为j 20 | f[i][j][j]+=mi10[i]; 21 | for(int d=0;d<=9;d++){//统计d 22 | for(int k=0;k<=9;k++){//下一层数字为k 23 | f[i][j][d]+=f[i-1][k][d]; 24 | } 25 | } 26 | } 27 | //统计j=10,即前置0的情况 28 | for(int d=0;d<=9;d++){//统计d有多少个 29 | for(int k=1;k<=10;k++){//下一层数字为k 30 | f[i][10][d]+=f[i-1][k][d]; 31 | } 32 | } 33 | } 34 | } 35 | void calc(long long x,long long ans[]){ 36 | int t[MAXL+1]={0}; 37 | int k=0; 38 | while(x>0){ 39 | int d=x % 10; 40 | t[k]=d; 41 | k++; 42 | x= x / 10; 43 | } 44 | int tot=-1; 45 | for(int k=0;k<=9;k++) ans[k]=0; 46 | int w=max(k-1,0); 47 | for(int i=w;i>=0;i--){ 48 | int d=t[i]; 49 | if (tot<0){//最高位时,应该加上的是前置0的情形 50 | //然后加1到d-1的情形 51 | if (d>0) { 52 | for(int k=0;k<=9;k++) ans[k]+=f[i][10][k]; 53 | } 54 | for(int j=1;ji;k--) { 61 | ans[t[k]]+=mi10[i]; 62 | } 63 | } 64 | } 65 | ans[d]++; 66 | tot=d; 67 | } 68 | } 69 | int main(){ 70 | mi10[0]=1; 71 | for(int i=1;i<=MAXL;i++) mi10[i]=10*mi10[i-1]; 72 | dp(); 73 | fin>>a>>b; 74 | a=a-1; 75 | calc(a,ans1); 76 | calc(b,ans2); 77 | for(int k=0;k<=9;k++) fout< 2 | #include 3 | #include 4 | 5 | using namespace std; 6 | const int MAXN=500000; 7 | string s; 8 | vector tree[MAXN+1]; 9 | int dp_max[MAXN+1][3],dp_min[MAXN+1][3]; 10 | int index; 11 | int n; 12 | void buildTree(int u){ 13 | int childNum=s[u-1]-'0'; 14 | for(int k=0;k>s; 50 | n=s.length(); 51 | index=1; 52 | buildTree(1); 53 | // for(int u=1;u<=n;u++){ 54 | // cout< 2 | #include 3 | #include 4 | 5 | using namespace std; 6 | const int MAXN=299995; 7 | struct Edge{ 8 | int u,v; 9 | }; 10 | int t,n; 11 | vector tree[MAXN+1]; 12 | int count[MAXN+1]; 13 | bool visited[MAXN+1]; 14 | Edge edges[MAXN]; 15 | Edge delEdge; 16 | 17 | void dfs_calc(int u){ 18 | visited[u]=true; 19 | count[u]=1; 20 | int s=tree[u].size(); 21 | for(int k=0;kx){ 41 | hasLarge=true; 42 | largeNode=v; 43 | break; 44 | }else if (2*count[v]==count[u]){ 45 | equalCount++; 46 | equalNode=v; 47 | } 48 | } 49 | if (hasLarge){ 50 | int all=count[u]; 51 | count[u]=all-count[largeNode]; 52 | count[largeNode]=all; 53 | return dfs_zx(largeNode); 54 | }else if (equalCount>0){ 55 | return u+equalNode; 56 | }else return u; 57 | } 58 | int main(){ 59 | cin>>t; 60 | for(int i=0;i>n; 62 | for(int j=1;j<=n;j++) tree[j].clear(); 63 | for(int j=0;j>u>>v; 66 | tree[u].push_back(v); 67 | tree[v].push_back(u); 68 | edges[j]={u,v}; 69 | } 70 | int ans=0; 71 | for(int j=0;j 4 | #include 5 | using namespace std; 6 | const int MAXN=1000,key=10000; 7 | struct number_stack{ 8 | long ele[MAXN]; 9 | int top=0; 10 | void push(long x){ 11 | ele[top]=x; 12 | top++; 13 | } 14 | void pop(){ 15 | top--; 16 | } 17 | long get_top(){ 18 | return ele[top-1]; 19 | } 20 | bool empty(){ 21 | return top==0; 22 | } 23 | int size(){ 24 | return top; 25 | } 26 | }; 27 | struct operator_stack{ 28 | char ele[MAXN]; 29 | int top=0; 30 | void push(char x){ 31 | ele[top]=x; 32 | top++; 33 | } 34 | void pop(){ 35 | top--; 36 | } 37 | char get_top(){ 38 | return ele[top-1]; 39 | } 40 | bool empty(){ 41 | return top==0; 42 | } 43 | }; 44 | number_stack ns; 45 | operator_stack os; 46 | int priority[256]; 47 | 48 | long str2int(string &s){ 49 | long ret; 50 | stringstream ss(s); 51 | ss>>ret; 52 | return ret; 53 | } 54 | int main(){ 55 | //在此添加需要用到的运算符的优先级,如果有括号,左括号的优级应该高于其他运算符 56 | //右括号的优先级低于其他运算符 57 | priority['#']=-1; 58 | priority['+']=0; 59 | priority['*']=1; 60 | 61 | string s; 62 | getline(cin,s); 63 | s=s+'#'; 64 | int l=s.length(); 65 | string tmp=""; 66 | 67 | for(int i=0;i='0'&&c<='9'){ 70 | tmp+=c; 71 | }else{ 72 | if (tmp!="") { 73 | ns.push(str2int(tmp)); 74 | tmp=""; 75 | } 76 | if (c=='+'||c=='*'||c=='#'){ 77 | while (!os.empty()){ 78 | char pre_c=os.get_top(); 79 | if (pre_c=='#') os.pop(); 80 | else if (priority[c]<=priority[pre_c]){ 81 | if (ns.size()<2) { 82 | return 0; 83 | }else { 84 | long a=ns.get_top(); 85 | ns.pop(); 86 | long b=ns.get_top(); 87 | ns.pop(); 88 | long ans; 89 | switch (pre_c){ 90 | case '+': 91 | ans=a+b; 92 | break; 93 | case '*': 94 | ans=a*b; 95 | break; 96 | } 97 | ans=ans%key; 98 | ns.push(ans); 99 | os.pop(); 100 | } 101 | }else break; 102 | } 103 | os.push(c); 104 | }else continue; 105 | } 106 | } 107 | cout< 2 | #include 3 | #include 4 | 5 | using namespace std; 6 | ifstream fin("travel.in"); 7 | ofstream fout("travel.out"); 8 | 9 | const int MAXN=200000; 10 | vector graph[MAXN]; 11 | int dp_max1[MAXN];//dp_max1[i]表示以i为根的子树中,根i到叶子结点的最长路径长度 12 | int dp_max2[MAXN];//dp_max2[i]表示以i为根的子树中,根i到叶子结点的次长路径长度 13 | int dp_max3[MAXN];//dp_max2[i]表示以i为根的子树的直径 14 | 15 | 16 | bool on_max_path[MAXN]; 17 | int last_max_len; 18 | int n; 19 | int parent[MAXN]; 20 | void dp(int u){ 21 | int count=graph[u].size(); 22 | int s1=0; 23 | int s2=0; 24 | int s3=0; 25 | int next=-1; 26 | for(int k=0;ks1) { 32 | s2=s1; 33 | s1=dp_max1[v]+1; 34 | }else if (dp_max1[v]+1>s2) 35 | s2=dp_max1[v]+1; 36 | if (dp_max3[v]>s3) s3=dp_max3[v]; 37 | } 38 | } 39 | dp_max1[u]=s1; 40 | dp_max2[u]=s2; 41 | dp_max3[u]=max(dp_max1[u]+dp_max2[u],s3); 42 | } 43 | //在以u为根的子树下,搜根u到叶子结点长度为len的路径 44 | void dfs1(int u,int len){ 45 | if (len<0) return;//只有一个节点的时候,它的长度为0,也要搜索 46 | on_max_path[u]=true; 47 | int count=graph[u].size(); 48 | for(int k=0;k>n; 72 | for(int i=0;i>u>>v; 75 | graph[u].push_back(v); 76 | graph[v].push_back(u); 77 | } 78 | memset(parent,-1,sizeof(parent)); 79 | dp(0); 80 | last_max_len=dp_max3[0]; 81 | dfs2(0,last_max_len); 82 | for(int i=0;i 3 | #include 4 | #include 5 | #include ; 6 | 7 | using namespace std; 8 | const int MAXN=100000; 9 | const int MAXJ=20; 10 | int n,m; 11 | char cow[MAXN+1]; 12 | vector G[MAXN+1]; 13 | int parent[MAXN+1]; 14 | int f[MAXN+1][MAXJ+1]; 15 | int d[MAXN+1]; 16 | int sum_hcow[MAXN+1];//从根到此节点H的累计数 17 | int sum_gcow[MAXN+1];//从根到此节点G的累计数 18 | //深搜预处理每个节点的深度和他的父节点(即f[x][0]) 19 | void pre(int x,int fa){ 20 | if (cow[x]=='H') { 21 | sum_hcow[x]=sum_hcow[fa]+1; 22 | sum_gcow[x]=sum_gcow[fa]; 23 | }else { 24 | sum_hcow[x]=sum_hcow[fa]; 25 | sum_gcow[x]=sum_gcow[fa]+1; 26 | } 27 | f[x][0]=fa; 28 | d[x]=d[fa]+1; 29 | for(int k=0;k=0;j--) if (d[f[x][j]]>=d[y]) x=f[x][j];//先通过跳让两个节点的深度一致 40 | if (x==y) return y; 41 | for(int j=MAXJ;j>=0;j--) //如果不同继续跳 42 | if (f[x][j]!=f[y][j]) { 43 | x=f[x][j]; 44 | y=f[y][j]; 45 | } 46 | return f[x][0]; 47 | } 48 | int main(){ 49 | cin>>n>>m; 50 | for(int i=1;i<=n;i++) cin>>cow[i]; 51 | for(int k=1;k>x>>y; 54 | G[x].push_back(y); 55 | G[y].push_back(x); 56 | } 57 | pre(1,0);//预处理计算出每个节点跳2^0次到达的节点 58 | //倍增计算出每个节点跳2^j次到达的节点(1<=j<=20) 59 | for(int j=1;j<=MAXJ;j++) 60 | for(int i=1;i<=n;i++){ 61 | f[i][j]=f[f[i][j-1]][j-1]; 62 | } 63 | 64 | for(int i=1;i<=m;i++){ 65 | int a,b; 66 | char c; 67 | cin>>a>>b>>c; 68 | if (cow[a]==c||cow[b]==c) cout<<1; 69 | else { 70 | int gf=lca(a,b); 71 | if (cow[gf]==c) cout<<1; 72 | else { 73 | if (c=='H') { 74 | if (sum_hcow[a]-sum_hcow[gf]>0||sum_hcow[b]-sum_hcow[gf]>0) cout<<1; 75 | else cout<<0; 76 | }else { 77 | if (sum_gcow[a]-sum_gcow[gf]>0||sum_gcow[b]-sum_gcow[gf]>0) cout<<1; 78 | else cout<<0; 79 | } 80 | } 81 | } 82 | } 83 | //system("pause"); 84 | } -------------------------------------------------------------------------------- /[洛谷题单]图论之连通性问题/P2341.cpp: -------------------------------------------------------------------------------- 1 | //P2341 [USACO03FALL][HAOI2006]受欢迎的牛 G 2 | #include 3 | #include 4 | #include 5 | #include 6 | using namespace std; 7 | const int MAXN=10010; 8 | const int MAXM=50010; 9 | struct Edge{ 10 | int from,to; 11 | }; 12 | Edge edges[MAXM+1]; 13 | vector G[MAXN+1],GNew[MAXN+1]; 14 | stack st; 15 | bool inStack[MAXN+1]; 16 | int scc[MAXN+1]; 17 | int sccIndex; 18 | int no; 19 | int sccNodeNum[MAXN+1]; 20 | int dfn[MAXN+1],low[MAXN+1]; 21 | int rudu[MAXN+1]; 22 | void tarjan(int u){ 23 | dfn[u]=low[u]=++no; 24 | st.push(u); 25 | inStack[u]=true; 26 | for(int k=0;k>n>>m; 64 | for(int k=0;k>u>>v; 67 | G[v].push_back(u);//逆向图 68 | edges[k]={v,u}; 69 | } 70 | for(int u=1;u<=n;u++) if (!dfn[u]) tarjan(u); 71 | for(int k=0;k 3 | #include 4 | #include 5 | 6 | using namespace std; 7 | ifstream fin("award.in"); 8 | ofstream fout("award.out"); 9 | 10 | const int MAXN=100; 11 | struct edge{ 12 | int u,v,w; 13 | bool operator<(const edge other)const{ 14 | return w edges; 18 | int w[MAXN+1][MAXN+1]; 19 | struct node{ 20 | int head,next,last,length; 21 | }; 22 | struct union_find_set{ 23 | node ele[MAXN+1]; 24 | void make_set(){ 25 | for(int i=1;i<=MAXN;i++) ele[i]={i,0,i,1}; 26 | } 27 | void union_set(int x,int y){ 28 | int hx=find_set(x); 29 | int hy=find_set(y); 30 | if (hx!=hy){ 31 | if (ele[hx].length>n>>m; 53 | for(int i=0;i>a>>b>>c; 56 | w[a][b]=c; 57 | w[b][a]=c; 58 | edges.push_back({a,b,c}); 59 | } 60 | sort(edges.begin(),edges.begin()+edges.size()); 61 | ufs.make_set(); 62 | int ans=1; 63 | int c=0; 64 | for(int i=0;i=n-1) break; 83 | } 84 | fout< 3 | #include 4 | #include 5 | 6 | using namespace std; 7 | const int MAXN=100000; 8 | int n,k; 9 | struct Edge{ 10 | int to,weight; 11 | }; 12 | vector G[MAXN+1]; 13 | int maxlen[MAXN+1]; 14 | int maxlen_to[MAXN+1]; 15 | int second_maxlen[MAXN+1]; 16 | int second_maxlen_to[MAXN+1]; 17 | 18 | void tree_dp(int u,int fa){ 19 | for(int k=0;kmaxlen[u]){ 26 | second_maxlen[u]=maxlen[u]; 27 | second_maxlen_to[u]=maxlen_to[u]; 28 | maxlen[u]=v_w; 29 | maxlen_to[u]=v; 30 | }else if (v_w>second_maxlen[u]){ 31 | second_maxlen[u]=v_w; 32 | second_maxlen_to[u]=v; 33 | } 34 | } 35 | } 36 | } 37 | void adjust(int u){ 38 | for(int k=0;k>n>>k; 49 | for(int i=1;i>a>>b; 52 | G[a].push_back({b,1}); 53 | G[b].push_back({a,1}); 54 | } 55 | tree_dp(1,0);//选定1为根结点后,求出以节点i为根结点的子树中最长路径和次长路径 56 | //第一次求树的最长路径(即直径) 57 | int d=0; 58 | int d_u; 59 | for(int u=1;u<=n;u++){ 60 | if (maxlen[u]+second_maxlen[u]>d){ 61 | d=maxlen[u]+second_maxlen[u]; 62 | d_u=u; 63 | } 64 | } 65 | int ans=2*(n-1)-d+1;//将树的直径的两个末端点相连,可使用巡逻少(d-1) 66 | if (k==2) {//修建第二条 67 | //找到树的一条直径,将上面的每一条边的weight由1调整为-1; 68 | for(int k=0;kd){ 82 | d=maxlen[u]+second_maxlen[u]; 83 | } 84 | } 85 | ans=ans-d+1; 86 | } 87 | cout<