哈尔滨理工大学软件学院ACM程序设计全国邀请赛【不断更新】

    xiaoxiao2021-12-14  19

    C:给定N和M,要求用N个数,这些数的和要能够覆盖1~M中的所有数,求这些数的方案总数

    看到N和M最大200,猜想是打表,但是没想明白怎么搞:看到标程,一眼题

    dp【i】【j】【k】:用i个数,这些数的和要能够覆盖1~M中的所有数,其中最大数是k

    要求最后的答案ans=dp【n】【m】【1】+dp【n】【m】【2】+dp【n】【m】【3】+……+dp【n】【m】【m】

    转移怎么想呢:

    枚举可以取到的最大值,至少为k,最大为j+1,还要满足和不超过极限值200的条件

    所以,全部可以提前打表预处理好的

    #include<bits/stdc++.h> using namespace std; #define LL long long #define mod 2000000007 const int maxn=220; LL dp[maxn][maxn][maxn],ans; int T,n,m; int main(){ memset(dp,0,sizeof(dp)); dp[1][1][1]=1; for(int i=1;i<=200;i++) for(int j=1;j<=200;j++) for(int k=1;k<=200;k++){ if (dp[i][j][k]==0) continue; for(int Max=k;Max+j<=200&&Max<j+2;Max++) dp[i+1][j+Max][Max]=(dp[i+1][j+Max][Max]+dp[i][j][k])%mod; } scanf("%d",&T); while(T--){ scanf("%d%d",&n,&m); ans=0; for(int Max=1;Max<=m;Max++) ans=(ans+dp[n][m][Max])%mod; printf("%lld\n",ans); } return 0; }

    E:求有多少个连续区间里,全部是6

    直接从前到后扫描一遍就好了,注意int和long long

    #include<bits/stdc++.h> using namespace std; #define LL long long const int maxn=2e5+50; char s[maxn]; LL ans; int T,n,num; int main(){ scanf("%d",&T); while(T--){ scanf("%d%s",&n,s); ans=0;num=0; for(int i=0;i<n;i++){ if (s[i]=='6') num++; else num=0; ans+=num; } printf("%lld\n",ans); } return 0; }

    L题先给题目一个好评,再给自己一个中评,分析: 看到这种四个这么大的数字,而且还有非法的情况-1要判断,肯定是个构造题(想到了可怕的青岛B题魔方)这种题分析思路更重要吧,写出心路历程

    首先,a3和a4比较重要,因为判断构造的形式

    如果a3=a4,68686或者86868都可以 如果a3=a4+1,那么68要比86多一个,686868这样的 如果a4=a3+1,那么868686这样的

    我们不能一直这样分类下去:在尝试无法构造其他的可能情况下,试图证明: 假设a3=a4+2,那么必须要出现6868这种的两个子段,那么用什么数字连接呢? 686866868和686886868,注意:这是可能的两种连接方式,但是,都会产生出来一个86!所以,不能出现a3>=a4+2的情况,同理对称的情况就不会出现了

    总情况分类就是上面的三种:接下来需要数数,判断6和8的个数是不是可以满足至少的要求! 多的8是尽可能放在后面的,多的6是尽可能放在前面的(废话:因为要求数最小)

    有了这些,分类打表就不难处理了

    #include<bits/stdc++.h> using namespace std; int a1,a2,a3,a4; int main(){ while(scanf("%d%d%d%d",&a1,&a2,&a3,&a4)!=EOF){ if (abs(a3-a4)>1) puts("-1"); else if (a3==a4){ if (a1>a3&&a2>=a3){ for(int i=1;i<=a1-a3;i++) printf("6"); for(int i=1;i<a3;i++) printf("86"); for(int i=1;i<=a2-a3;i++) printf("8"); puts("86"); } else if (a1>=a3&&a2>a3){ printf("86"); for(int i=1;i<=a1-a3;i++) printf("6"); for(int i=1;i<a3;i++) printf("86"); for(int i=1;i<=a2-a3;i++) printf("8"); puts(""); } else puts("-1"); } else if (a3==a4+1){ if (a1>=a3&&a2>=a3){ for(int i=1;i<=a1-a3;i++) printf("6"); for(int i=1;i<=a3;i++) printf("68"); for(int i=1;i<=a2-a3;i++) printf("8"); puts(""); } else puts("-1"); } else if (a4==a3+1){ if (a1>=a4&&a2>=a4){ printf("86"); for(int i=1;i<=a1-a4;i++) printf("6"); for(int i=1;i<=a4-2;i++) printf("86"); for(int i=1;i<=a2-a4;i++) printf("8"); puts("86"); } else puts("-1"); } } return 0; }

    转载请注明原文地址: https://ju.6miu.com/read-970044.html

    最新回复(0)