A. 符號化方法初探
看最大數和最小數的絕對值大小,用至多 \(n-1\) 次讓其符號相同,是正數就加前一個數,是負數就倒著加後一個數,最多
\(n-2\) 次。
點選檢視程式碼
#include<bits/stdc++.h>
const int maxn=2e5+10;
using namespace std;
int n,a[maxn],x[maxn],y[maxn],cnt,minn,maxx,ma,mi;
int main()
{
ios::sync_with_stdio(0);
cin.tie(0),cout.tie(0);
cin>>n;
maxx=-2e9;
minn=2e9;
for(int i=1;i<=n;i++)
{
cin>>a[i];
if(a[i]>maxx) maxx=a[i],ma=i;
if(a[i]<minn) minn=a[i],mi=i;
}
if(-minn>maxx)
{
for(int i=1;i<=n;i++)
{
if(a[i]>0)
{
// a[i]+=minn;
x[++cnt]=mi,y[cnt]=i;
}
}
for(int i=n-1;i>=1;i--)
{
// a[i]+=a[i+1];
x[++cnt]=i+1,y[cnt]=i;
}
}
else
{
for(int i=1;i<=n;i++)
{
if(a[i]<0)
{
// a[i]+=maxx;
x[++cnt]=ma,y[cnt]=i;
}
}
for(int i=2;i<=n;i++)
{
// a[i]+=a[i-1];
x[++cnt]=i-1,y[cnt]=i;
}
}
cout<<cnt<<'\n';
for(int i=1;i<=cnt;i++)cout<<x[i]<<" "<<y[i]<<'\n';
return 0;
}
/*
4
-1 -1 0 -1
*/
B. 無標號 Sequence 構造
思維題,\(n^3\) 暴力肯定不行,但他只問相不相等,所以我們可以構造一個 \(1*n\) 的矩陣,由於矩陣乘法滿足結合率,所以
我們先 \(n^2\) 讓等號兩邊矩陣都乘上構造矩陣再 \(n^2\) 判等即可
點選檢視程式碼
#include<bits/stdc++.h>
const int mod=998244353;
const int maxn=3010;
using namespace std;
int t,n,a[maxn][maxn],b[maxn][maxn],c[maxn][maxn],flag,aa[2][maxn],cc[2][maxn];
int main()
{
ios::sync_with_stdio(0);
cin.tie(0),cout.tie(0);
cin>>t;
while(t--)
{
flag=0;
cin>>n;
memset(aa,0,sizeof aa);
memset(cc,0,sizeof cc);
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)cin>>a[i][j];
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)cin>>b[i][j];
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)cin>>c[i][j];
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
aa[1][i]=(aa[1][i]+1ll*a[j][i]*(j%2+1)%mod)%mod;
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
cc[1][i]=(cc[1][i]+1ll*c[j][i]*(j%2+1)%mod)%mod;
for(int i=1;i<=n;i++)
{
long long temp=0;
for(int j=1;j<=n;j++)
{
temp=(temp+1ll*aa[1][j]*b[j][i])%mod;
// cout<<temp<<" "<<cc[1][i]<<endl;
}
if(temp!=cc[1][i])flag=1;
if(flag)break;
}
if(flag) cout<<"No"<<'\n';
else cout<<"Yes"<<'\n';
}
return 0;
}
D. 有限制的構造
一個\(dp\),但我 \(dp\) 一直不太好
初始模型是 \(f_{i,j,k}\) 表示前 \(i\) 個,畫面質量是 \(j\) ,不可玩度是 \(k\) 時的個數,但陣列開不下,遂捨棄
觀察到 \(n\) 最大80,所以我們可以把答案放陣列裡,則\(f_{i,j,k}\) 表示前 \(i\) 個,選 \(j\) 個,畫面質量是 \(k\) 時,的不可玩度最小值
我們強制讓 \(k\) 在範圍內,最後再隨便選一個即可,但 \(256MiB\),還是開不下,滾動陣列最佳化一下就好了
點選檢視程式碼
#include<bits/stdc++.h>
const int maxn=1e4+10;
using namespace std;
int n,A,B,ans,a[100],b[100],f[2][82][maxn];
int main()
{
ios::sync_with_stdio(0);
cin.tie(0),cout.tie(0);
cin>>n>>A>>B;
for(int i=1;i<=n;i++)
cin>>a[i]>>b[i];
memset(f,0x7f,sizeof f);
f[1][0][0]=f[0][0][0]=0;
for(int i=1;i<=n;i++)
{
int temp=i&1;
for(int j=1;j<=i;j++)
{
for(int k=0;k<=A;k++)
{
if(k>=a[i])f[temp][j][k]=f[temp^1][j-1][k-a[i]]+b[i];
f[temp][j][k]=min(f[temp][j][k],f[temp^1][j][k]);
}
}
}
for(int i=n;i>=0;i--)
{
for(int j=0;j<=A;j++)
{
if(f[1][i][j]<=B||f[0][i][j]<=B)
{
cout<<min(i+1,n);
return 0;
}
}
}
return 0;
}