幾道不錯的TC題
阿新 • • 發佈:2018-11-10
文章目錄
如果大家在TC的哪一場見到過這幾題務必告訴我,我將不勝感激.
T1
要想保證獲得
個球有三種方法:
- 第一種,直接去找紅色球,買 個盒子,盒子裡表明紅球的總個數是 或者更多.
- 同理,直接去買藍色球.
- 買的盒子裡的紅藍兩種球的總個數是 或者更多,這樣子不管如何,都能夠有一種球的個數大於或者等於 .
我們利用這樣的思路,跑三次01揹包,求出花費的最小值.
轉化清奇的一道01揹包,不錯的題.
#include<bits/stdc++.h> //Ithea Myse Valgulious
using namespace std;
const int yuzu=1e5,inf=0x3f3f3f3f;
typedef int fuko[yuzu|10];
fuko a,b,c,d,dp;
int bao(int *v,int k,int n){
int i,j;
fill(dp+1,dp+yuzu,inf);
for (i=1;i<=n;++i)
for (v[i]--,j=k;~j;--j)
dp[min(k,j+v[i])]=min(dp[min(k,j+v[i])],dp[j]+c[i]);
return dp[k];
}
int main(){
int i,n,k,j; read(n),read(k);
for (i=1;i<=n;++i) a[i]=read();
for (i=1;i<=n;++i) d[i]=a[i]+1+(b[i]=read());
for (i=1;i<=n;++i) c[i]=read();
/*d[i]=a[i]+b[i]*/
int llx=min(bao(d,k*2-1,n),min(bao(a,k,n),bao(b,k,n)));
write(llx^inf?llx:-1);
}
T2
這個東西有兩維,用普通的方法很難計算.
我們考慮用排序先消掉一維的複雜度.
將點按照點權排序,每次加入一個點,用
更新已經加入的兩點之間的最大路和路徑的最小難度值.
資料範圍一小下來我瞬間就爆炸了,連
都想不到了.
#include<bits/stdc++.h> //Ithea Myse Valgulious
using namespace std;
const int aoi=3058,inf=0x3f3f3f3f;
typedef int nao[aoi];
nao a,b,dis[aoi],v,id;
ll ans[aoi][aoi];
int main(){
int i,n,m,j,k;
read(n),read(m);
memset(dis,0x3f,sizeof dis);
memset(ans,0x3f,sizeof ans);
for (i=1;i<=m;++i) a[i]=read()+1;
for (i=1;i<=m;++i) b[i]=read()+1;
for (i=1;i<=m;++i){
int d=read();
dis[a[i]][b[i]]=min(dis[a[i]][b[i]],d);
dis[b[i]][a[i]]=min(dis[b[i]][a[i]],d);
}// 資料有重邊!
for (i=1;i<=n;++i)
v[i]=read(),dis[i][i]=ans[i][i]=0,id[i]=i;
for (i=1;i<=n;++i){
for (j=1;j<n;++j)
if (v[id[j]]>v[id[j+1]]) swap(id[j],id[j+1]);
}
/*資料範圍小的時候我會習慣性用氣泡排序.下面那句sort與上面的兩個迴圈效果相同.*/
//sort(id+1,id+n+1,[&](int a,int b){return v[a]<v[b];});
ll llx=0;
for (k=1;k<=n;++k){
for (i=1;i<=n;++i)
for (j=1;j<=n;++j)
dis[i][j]=min(dis[i][j],max(dis[i][id[k]],dis[id[k]][j])); //floyd更新最大邊
for (i=1;i<=k;++i)
for (j=1;j<=k;++j)
if (dis[id[i]][id[j]]<inf)
ans[id[i]][id[j]]=min(ans[id[i]][id[j]],1ll*dis[id[i]][id[j]]*v[id[k]]); // 更新d(i,j)
}
for (i=1;i<=n;++i)
for (j=i+1;j<=n;++j) llx+=ans[i][j];
write(llx);
}
T3
超級好題,我要吹爆它!這是我見過最有意思的構造題!