cf1680e
// https://codeforces.com/problemset/problem/1680/E
#include<bits/stdc++.h>
using namespace std;
void fileio()
{
//#ifdef LGS
freopen("in.txt","r",stdin);
freopen("out.txt","w",stdout);
//#endif
}
const int N = 2e5 + 10;
int mp[2][N];
int dp[2][N]; // dp[0/1][i] clear 前 i-1 列 到达 (i,0/1);
int n;
void solve()
{
cin >> n; for(int i = 1;i <= n;i ++) dp[0][i] = dp[1][i] = 0;
for(int i = 0;i < 2;i ++) for(int j = 1;j <= n;j ++)
{
char c; cin >> c; mp[i][j] = (c == '*');
}
int l = 1;int r = n;
while(mp[0][l] == 0 && mp[1][l] == 0) l++;
while(mp[0][r] == 0 && mp[1][r] == 0) r--;
for(int i = l;i <= r;i ++)
{
dp[0][i] = min(dp[0][i-1] + 1 + mp[1][i], dp[1][i-1] + 2);
dp[1][i] = min(dp[1][i-1] + 1 + mp[0][i], dp[0][i-1] + 2);
}
cout << min(dp[0][r],dp[1][r])-1 << endl;
}
int main()
{
fileio();
int _; cin >> _;
while(_--) solve();
}
cf1312e
dp[l][r] 表示 从l到r 合并区间后 长度的最小值;
w[l][r] 表示 sum of l ~ r
#include<bits/stdc++.h>
#define endl '\n'
#define int long long
using namespace std;
const int N = 510;
int n;
int a[N];
int dp[N][N];
int w[N][N];
void fileio()
{
//#ifdef LGS
freopen("in.txt","r",stdin);
freopen("out.txt","w",stdout);
//#endif
}
void solve(){
memset(dp,10000,sizeof dp);
cin >> n;
for(int i = 1;i <= n;i ++){ cin >> a[i];dp[i][i]= 1; w[i][i] = a[i];}
for(int len = 2;len <= n; len ++)
for(int l = 1;l + len - 1 <= n;l ++){
int r = l + len - 1;
for(int mid = l;mid < r;mid ++)
{
dp[l][r] = min(dp[l][r], dp[l][mid] + dp[mid + 1][r]);
if(dp[l][mid] == dp[mid + 1][r] && dp[l][mid] == 1 && w[l][mid] == w[mid + 1][r])
dp[l][r] = 1,w[l][r] = w[l][mid] + 1;
}
}
cout << dp[1][n] << endl;
}
signed main()
{
ios::sync_with_stdio(false);cin.tie(0);
//fileio();
solve();
}
cf1257e
题意,三个集合abc,合起来不重不漏覆盖1
到n
。
每一次操作可以将一个数从一个集合移到另外的一个集合。
问需要几次操作使得集合a的所有元素 < b中所有元素 < c中所有元素。
集合可以变成空集合。
稍微想一下,会发现,a,b,c可以直接sort一下。
考虑两个集合的情况
假设样例
1 2 3 5
4 6
观察一下可以将4
移上去或者将5
移动下来;我们发现有坑这种结构;
对于a数组,我们每个数字的坑就是value - postion 即 a[i] - i;
我们再随机造一个复杂的样例
1 3 5 6 7 9 10
2 4 8 11 12
即
1 (2) 3 (4)5 6 7 (8) 9 10
选定一个位置 i a[i]之后的所有数移动到其他数列的代价是 lena - i
使i
之前的数列合法的代价是 a[i]-i;
一旦 a 合法,b连锁合法。
所以res 等于 min(lena - i + a[i] - i) for(i from 1 to lena)
然后看abc的情况
cf1582e
#include<bits/stdc++.h>
#define int long long
using namespace std;
void fileio()
{
//#ifdef LGS
freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
//#endif
}
const int N = 1e5 + 10;
const int M = 550;
const int INF = 0x3f3f3f3f;
int n;
int a[N];
int sum[N];
int dp[M][N];
void solve()
{
cin >> n;
for(int i = 1;i <= n;i ++) cin >> a[i];
for(int i = 1;i <= n;i ++) sum[i] = (sum[i-1]+a[i]);
for(int k = 1;k <= 500;k ++) for(int i = 0;i <= n + 5;i ++)
dp[k][i] = 0;
for(int i = 0;i <= n + 1;i ++) dp[0][i] = INF;
for(int i = n ;i >= 1;i --) for(int k = 1;k <= 500;k ++)
{
dp[k][i] = dp[k][i + 1];
// i 是枚举考虑到 第i个位置 k是当前枚举到第k个区间,区间长度也为k
// dp的值是 表示第k个区间区间和的最大值
if(i + k - 1 <= n && sum[i + k - 1] - sum[i - 1] < dp[k-1][i+k])// 合法转移
dp[k][i]=max(dp[k][i],sum[i+k-1]-sum[i-1]);
}
//int res = 1;
for(int i = 500;i >= 1;i --) if(dp[i][1]) {cout << i << endl; return;}
cout << 1 << endl;
}
signed main()
{
std::ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
//fileio();
int T;cin >> T;
while(T --)solve();
//solve();
}
cf1516c
#include<bits/stdc++.h>
#define int long long
using namespace std;
void fileio()
{
//#ifdef LGS
freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
//#endif
}
const int N = 110;
const int M = 2e5 + 20;
bool dp[M];
int a[N];
int n;
inline int gcd(int a,int b)
{
return b ? gcd(b,a%b) : a;
}
void solve()
{
cin >> n; for(int i = 1;i <= n;i ++) cin >> a[i];
memset(dp,false,sizeof dp); dp[0] = true;
int GCD = 0; int sum = 0;
for(int i = 1;i <= n;i ++) GCD = gcd(GCD,a[i]);
//for(int i = 1;i <= n;i ++) sum += a[i];
for(int i = 1;i <= n;i ++) a[i] /= GCD, sum += a[i];
for(int i = 1; i <= n; i ++ )for(int j = M - 10; j >= a[i]; j -- )
dp[j] = dp[j - a[i]] ? true : dp[j];
//cout << sum/2 << endl;
//cout << dp[sum/2] << endl;
if(sum % 2 == 0 && dp[sum/2])
{
cout << 1 << endl;
for(int i = 1;i <= n;i ++) if(a[i]&1) {cout << i << endl;return;}
}
else cout << 0 << endl;
}
signed main()
{
std::ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
//fileio();
int T = 1;//cin >> T;
//while(T --)solve();
solve();
}