Submission #257746

#TimeUsernameProblemLanguageResultExecution timeMemory
257746amiratouPopeala (CEOI16_popeala)C++14
100 / 100
1673 ms50692 KiB
#pragma GCC optimize("O3") #include <bits/stdc++.h> using namespace std; #define boost ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0) #define rando mt19937 rng(chrono::steady_clock::now().time_since_epoch().count()) #define fi first #define se second #define debug(x) cerr << " - " << #x << ": " << x << endl; #define debugs(x, y) cerr << " - " << #x << ": " << x << " " << #y << ": " << y << endl; #define debugii(x) cerr << " - " << #x << ": " << x.fi<<","<<x.se << endl; #define sep() cerr << "--------------------" << endl; #define all(x) (x).begin(),(x).end() #define sz(x) (ll)x.size() #define ld long double #define ll long long //#define int ll #define ii pair<int,int> #define v vector<int> #define vii vector<ii> #define vv vector<vector<int> > #define mp make_pair #define pb push_back #define EPS 1e-9 const int INF = 2000000009; const int MOD = 1000000007; // 998244353 const int MX_t = 20003 , MX_n = 53; int n,t,s,p[MX_t],A[MX_t][MX_n],dp[MX_n][MX_t],pre[MX_n][MX_t],par[MX_t]; string S; vii ranges[MX_n][MX_t]; int find_set(int i){ if(par[i]==i)return i; return par[i]=find_set(par[i]); } int32_t main(){ boost; //freopen(".in","r",stdin); cin>>n>>t>>s; for (int i = 1; i <= t; ++i) { cin>>p[i]; if(i)p[i]+=p[i-1]; } for (int i = 0; i < n; ++i) { cin>>S; for (int j = 1; j <= t; ++j) { if(S[j-1]=='0')A[j][i]=j; else A[j][i]=A[j-1][i]; } } for (int i = 1; i <= t; ++i) { A[i][n]=i; sort(A[i],A[i]+n+1); } for (int i = 0; i < MX_n; ++i) for (int j = 0; j <= t; ++j) dp[i][j]=INF,pre[i][j]=INF; dp[0][0]=0; for (int j = 1; j <= t; ++j) { if(A[j][0])ranges[0][A[j][0]].pb({1,j}); for (int i = 0; i <= n; ++i) if((A[j][i]+1) <= A[j][i+1]) ranges[i+1][A[j][i+1]].pb({A[j][i]+1,j}); } for (int k = 1; k <= s; ++k) { for (int x = 0; x <= n; ++x) { stack<int> st; for (int j = 1; j <= t; ++j) par[j]=j; for (int j = 1; j <= t; ++j) { int val; if(dp[k-1][j-1]!=INF)val=dp[k-1][j-1]-p[j-1]*x; else val=INF; while(!st.empty() && ((dp[k-1][st.top()-1]==INF)?INF:(dp[k-1][st.top()-1]-p[st.top()-1]*x)) > val){ par[st.top()]=j; st.pop(); } st.push(j); for(auto it:ranges[x][j]){ int h=find_set(it.fi); if(dp[k-1][h-1]!=INF)pre[x][it.se]=dp[k-1][h-1]-p[h-1]*x; else pre[x][it.se]=INF; } } } for (int j = 1; j <= t; ++j) for (int x = 0; x <= n; ++x) if(pre[x][j]!=INF)dp[k][j]=min(dp[k][j],pre[x][j]+p[j]*x); cout<<dp[k][t]<<"\n"; } return 0; } //do smth instead of nothing and stay organized //long long //array bounds //special cases //binary search
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...