No 1. 一元三次方程求解
https://vijos.org/p/1116
看见有人认真推导了求解公式,然后猥琐暴力过的同学们在一边偷笑~~~
数据小 暴力枚举即可
1 double a,b,c,d; 2 double x; 3 4 int main() 5 { 6 ios_base::sync_with_stdio(0); 7 8 cin>>a>>b>>c>>d; 9 10 for(double i=-10000;i<=10000;i+=1) 11 { 12 x=i/100; 13 14 if(abs(a*x*x*x+b*x*x+c*x+d)<0.01) 15 { 16 printf("%.2f ",x); 17 } 18 } 19 20 return 0; 21 }
No 2. 数的划分
https://vijos.org/p/1117
dp/dfs
dp
用f(i,j)表示i这个数分成k份有多少种分法
毫无疑问
f[i][j]=f[i-1][j-1]+f[i-j][j];
因为 f(i,j) 可以从 f(i-1,j-1)推出 又要保持不下降的分划 所以可以从f(i-j,j)推出
1 int n,k; 2 int f[222][222]; 3 4 void init() 5 { 6 cin>>n>>k; 7 8 for(int i=1;i<=n;i++) 9 { 10 for(int j=1;j<=i;j++) 11 { 12 f[i][j]=inf; 13 } 14 } 15 16 for(int i=1;i<=n;i++) 17 { 18 f[i][1]=1; 19 } 20 } 21 22 int main() 23 { 24 init(); 25 26 for(int i=2;i<=n;i++) 27 { 28 for(int j=2;j<=i;j++) 29 { 30 f[i][j]=f[i-1][j-1]+f[i-j][j]; 31 } 32 } 33 34 cout<<f[n][k]<<endl; 35 36 return 0; 37 }
dfs
暴力枚举
只要不下降+剪枝就可以了
1 int n,k; 2 int ans; 3 4 void dfs(int nw,int sum,int num) 5 { 6 if(num==k) 7 { 8 if(sum==n) 9 { 10 ans++; 11 } 12 else 13 { 14 return; 15 } 16 } 17 18 if(sum==n) 19 { 20 return; 21 } 22 23 for(int i=nw;i<=n-sum;i++) 24 { 25 dfs(i,sum+i,num+1); 26 } 27 28 return; 29 } 30 31 int main() 32 { 33 ios_base::sync_with_stdio(0); 34 35 cin>>n>>k; 36 37 for(int i=1;i<=n/2;i++) 38 { 39 dfs(i,i,1); 40 } 41 42 cout<<ans<<endl; 43 44 return 0; 45 }
No 3. 统计单词个数
https://vijos.org/p/1118
dp
这几年dp考的好多啊
这题题解我真的不会写 我的写法我自己都看不懂
复制一段
划分这个DP,很基础。
然后,是sum[i][j],第i个字母到第j个字母一共可以形成多少个单词,ccy也用的Dp。
sum[i][j]=sum[i][-1]+(包含可以添加最后一个字母j的单词的总个数)。
ccy,WA在……比如现在可以添加一个新单词,k到j,但是,若果以k为起点,在sum[i][j-1]中已经有过单词,该新单词就不添加。于是乎,ccy光荣地WA掉一个点,因为,
那个点有两个相同的单词,我就扩展了两次。
1 string s; 2 int slen; 3 string words[maxm]; 4 int wordslen[maxm]; 5 int f[maxn][maxm]; 6 int sum[maxn][maxn]; 7 int n,k,m; 8 9 void init() 10 { 11 string tmp; 12 cin>>n>>k; 13 for (int i=1;i<=n;i++) 14 { 15 cin>>tmp; 16 s+=tmp; 17 } 18 slen=s.size(); 19 cin>>m; 20 for (int i=1;i<=m;i++) 21 { 22 cin>>words[i]; 23 wordslen[i]=words[i].size(); 24 } 25 } 26 27 int add(int l,int r) 28 { 29 int ans=0; 30 if (r-1>=0) ans=sum[l][r-1]; 31 bool vis[maxn]={0}; 32 for (int i=1;i<=m;i++) 33 { 34 int qd=r-wordslen[i]+1; 35 if (qd<l) continue; 36 if (qd==s.find(words[i],qd)) 37 { 38 if (vis[qd]) continue; 39 vis[qd]=1; 40 ans++; 41 for (int j=1;j<=m;j++) 42 { 43 int dq=r-wordslen[j]; 44 if (dq==qd) 45 if (dq==s.find(words[j],dq)) 46 { 47 ans--; 48 break; 49 } 50 } 51 } 52 } 53 return ans; 54 } 55 56 void gsum() 57 { 58 for (int i=0;i<=slen-1;i++) 59 for (int j=i;j<=slen-1;j++) 60 { 61 sum[i][j]=add(i,j); 62 } 63 } 64 65 void work() 66 { 67 for (int i=0;i<=slen-2;i++) 68 f[i][1]=sum[0][i]; 69 for (int i=0;i<=slen-2;i++) 70 for (int j=2;j<=min(k-1,i+1);j++) 71 for (int u=j-2;u<=i-1;u++) 72 f[i][j]=max(f[i][j],f[u][j-1]+sum[u+1][i]); 73 int ans=0; 74 if (k==0) 75 ans=sum[0][slen-1]; 76 else 77 for (int i=k-1;i<=slen-2;i++) 78 ans=max(ans,f[i][k-1]+sum[i+1][slen-1]); 79 printf("%d\n",ans); 80 } 81 82 int main() 83 { 84 int qn; 85 qn=1; 86 while(qn--) 87 { 88 init(); 89 gsum(); 90 work(); 91 } 92 93 return 0; 94 }
先写这么多 第四题下午再写
Bye~~~
时间: 2024-10-17 18:37:59