GUTC 2019/9/22题目
Posted sunyx20060115
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了GUTC 2019/9/22题目相关的知识,希望对你有一定的参考价值。
较水吧,直接区间dp
dp[i][j]显然表示区间答案,开头预处理出一个的和两个的
考虑转移
若当前的str[i]==str[j],必可以和原来的最后一段形成回文,然后一起删掉
若str[i]!=str[j],就枚举断点就ok了
#include<bits/stdc++.h> using namespace std; #define int long long int dp[1005][1005],n; string str; signed main() { for (int i=0;i<1000;++i) { for (int j=0;j<1000;++j) { dp[i][j]=1000000000; } } cin>>n>>str; for (int i=0;i<=n;++i) dp[i][i]=1; for (int i=0;i<n-1;++i) { if (str[i]==str[i+1]) dp[i][i+1]=1; else dp[i][i+1]=2; } for (int len=3;len<=n;++len) { for (int i=0;i+len<=n;++i) { int j=i+len-1; if (str[i]==str[j]) dp[i][j]=dp[i+1][j-1]; for (int k=i;k<j;++k) { dp[i][j]=min(dp[i][j],dp[i][k]+dp[k+1][j]); } } } printf("%lld ",dp[0][n-1]); return 0; }
考虑这题的复杂度差不多是O(n3),想到了神奇的floyd
这题还是挺巧的,但想到了还是挺好理解的
考虑怎么离线下来,把每条边权赋为当前的次数,然后把floyd改为求最大值
最后再求一下每个次数的有多少个就ok了
记得最后要记个前缀和,因为如果前面可以了,后面则也可行
#include<bits/stdc++.h> using namespace std; #define int long long const int INF=1000000000; int n,m,f[405][405],ans[160005]; signed main() { scanf("%lld%lld",&n,&m); for(int i=1;i<=n;++i) for(int j=1;j<=n;++j) f[i][j]=INF; for(int i=1;i<=m;++i) { int u,v; scanf("%lld%lld",&u,&v); f[u][v]=i; } for(int k=1;k<=n;++k) for(int i=1;i<=n;++i) { if(i==k) continue; for(int j=1;j<=n;++j) { if(j==i||j==k)continue; f[i][j]=min(f[i][j],max(f[i][k],f[k][j])); } } for(int i=1;i<=n;++i) { for(int j=1;j<=n;++j) { if(f[i][j]!=INF) ans[f[i][j]]++; } } for(int i=1;i<=m;++i) { ans[i]+=ans[i-1]; printf("%lld ",ans[i]); } return 0; }
比较好玩,就是没做过这种题的一般想不到(想到的一般都是像pmt,gh,杜神,于神这种教主了吧qwq)
康康数据范围:106 !!!
第一眼感觉是数学,但是数学题n才1e6???
然后想想,O(n)做法,结果失败了
经pmt一说,豁然开朗!!!pmt txdy!!!
原来建个图,考虑%n情况下,每个数可以到哪几个数
这样你就成功获得了72分!!!
然后考虑优化,其实用deque大力优化一下就行了
#include<bits/stdc++.h> using namespace std; #define int long long inline int read() { int x(0),neg(1);char ch(getchar()); while(!isdigit(ch)) { if (ch==‘-‘) neg=-1; ch=getchar(); } while(isdigit(ch)) { x=(x<<1)+(x<<3)+(ch^48); ch=getchar(); } return x*neg; } int vis[10000005]; int n; deque<pair<int,int> > q; signed main() { n=read(); q.push_front(make_pair(1,1)); while(!q.empty()) { pair<int,int> p=q.front(); q.pop_front(); if(!vis[p.first]) { vis[p.first]=1; if(p.first==0) { printf("%lld ",p.second); break; } q.push_front(make_pair((p.first*10)%n,p.second)); q.push_back(make_pair((p.first+1)%n,p.second+1)); } } return 0; }
以上是关于GUTC 2019/9/22题目的主要内容,如果未能解决你的问题,请参考以下文章