日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

打表+dp思维+博弈

發(fā)布時(shí)間:2024/3/12 编程问答 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 打表+dp思维+博弈 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

E. Sending a Sequence Over the Network

應(yīng)該屬于一個(gè)經(jīng)典dp,可惜我沒做出來(lái)。。。
思路:對(duì)于一個(gè)數(shù)字來(lái)說,它可以向左擴(kuò)展,也可以向有擴(kuò)展。
設(shè)計(jì)狀態(tài):f[i]表示第i位數(shù)字能否成功被包括
先討論f[i]是否和法,由狀態(tài)f[i-a[i]-1]轉(zhuǎn)移得到;只有f[i]被表示時(shí),才可將a[i+1]向右擴(kuò)展。

#include<bits/stdc++.h> #define int long long #define endl '\n' #define For(i,a,b) for(i=(a);i<=(b);++i) #define ios (ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)) using namespace std; const int N=2e5+5; const int inf=1e18; const int mod=998244353; int n,a[N],f[N];void solve() {cin >> n;for(int i=1;i<=n;i++) cin>>a[i],f[i]=0;f[0]=1;for(int i=0;i<=n;i++){if(i-a[i]-1>=0&&f[i-a[i]-1]) f[i]=1;if(!f[i]) continue;if(i+a[i+1]+1<=n&&f[i]) f[i+a[i+1]+1]=1;}if(f[n]) cout<<"YES"<<endl;elsecout<<"NO"<<endl; } signed main() {//ios;int T;cin>>T;while(T--)solve();return 0; }

C. Chef Monocarp

思路:KM算法求完美匹配的最大權(quán)值,左部點(diǎn)和右部點(diǎn)要求個(gè)數(shù)相同。
對(duì)于本題,左部點(diǎn)為烘培時(shí)間,右部點(diǎn)為拿出時(shí)間,因?yàn)槟贸鰰r(shí)間的不固定,構(gòu)建虛點(diǎn),連線權(quán)值要求為0,否則會(huì)對(duì)答案產(chǎn)生貢獻(xiàn)。
由于是最小權(quán)值,轉(zhuǎn)化為負(fù)值,邊初始化為-inf,跑KM算法.

#include<bits/stdc++.h> #define int long long #define endl '\n' #define For(i,a,b) for(i=(a);i<=(b);++i) #define ios (ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)) using namespace std; const int N=405; const int inf=1e18; const int mod=998244353; int n,a[N]; int w[N][N],lx[N],ly[N]; bool visx[N],visy[N]; int match[N],delta,c[N],p[N]; int A[N],P[N],B[N],C[N]; void bfs(int x) // O(n^3)的KM板子 {int a,y=0,y1=0;for(int i=1;i<=n;i++) p[i]=0,c[i]=inf;match[y]=x;do{a=match[y],delta=inf,visy[y]=1;for(int b=1;b<=n;b++){if(!visy[b]){if(c[b]>lx[a]+ly[b]-w[a][b])c[b]=lx[a]+ly[b]-w[a][b],p[b]=y;if(c[b]<delta) delta=c[b],y1=b;}}for(int b=0;b<=n;b++)if(visy[b]) lx[match[b]]-=delta,ly[b]+=delta;else c[b]-=delta;y=y1;}while(match[y]);while(y)match[y]=match[p[y]],y=p[y]; } int KM() {for(int i=1;i<=n;i++) match[i]=lx[i]=ly[i]=0;for(int i=1;i<=n;i++){for(int i=0;i<=n;i++) visy[i]=0;bfs(i);}int res=0;for(int i=1;i<=n;i++) res+=w[match[i]][i];return res; }void solve() {cin>>n;for(int i=1;i<=2*n;i++) a[i]=0;for(int i=1;i<=n;i++) cin>>a[i];for(int i=1;i<=2*n;i++)for(int j=1;j<=2*n;j++) w[i][j]=-inf;for(int i=1;i<=n*2;i++){for(int j=1;j<=n*2;j++){if(i<=n)w[i][j]=(-1)*abs(a[i]-j);else w[i][j]=0;}}n*=2;cout<<-KM()<<endl; } signed main() {ios;int T;cin>>T;while(T--)solve();return 0; }

dp算法:
dp[i][j]表示第i道菜在第j分鐘被拿出所需要的最小花費(fèi)。

#include<bits/stdc++.h> #define int long long #define endl '\n' #define For(i,a,b) for(i=(a);i<=(b);++i) #define ios (ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)) using namespace std; const int N=405; const int inf=1e18; const int mod=998244353; int n,a[N],dp[N][N];void solve() {cin>>n;for(int i=1;i<=n;i++) cin>>a[i];sort(a+1,a+n+1);for(int i=1;i<=n;i++) for(int j=0;j<=n*2;j++) dp[i][j]=inf;for(int i=1;i<=n;i++)for(int j=1;j<=n*2;j++){dp[i][j]=min(dp[i][j-1],dp[i-1][j-1]+abs(j-a[i]));//cout<<dp[i][j]<<endl;}int ans=inf;for(int i=1;i<=2*n;i++) ans=min(dp[n][i],ans);cout<<ans<<endl; } signed main() {//ios;int T;cin>>T;while(T--)solve();return 0; }

C. Even Number Addicts

思路:分清必勝態(tài)、必?cái)B(tài)、先后手影響、各自的最優(yōu)策略。
1.A想讓自己的總和為偶數(shù),偶數(shù)不會(huì)影響奇偶性,但奇數(shù)可以。
2.討論奇數(shù)的數(shù)目,及相應(yīng)偶數(shù)數(shù)量可能會(huì)產(chǎn)生的影響。

#include<bits/stdc++.h> #define int long long #define endl '\n' #define For(i,a,b) for(i=(a);i<=(b);++i) #define ios (ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)) using namespace std; const int N=405; const int inf=1e18; const int mod=998244353; int n,odd,even;void solve() {odd=even=0;cin>>n;for(int i=1;i<=n;i++){int x;cin>>x;if(x%2) odd++;else even++;}if(odd%4==0) cout<<"Alice"<<endl;else if(odd%4==1){if(even%2) cout<<"Alice"<<endl;else cout<<"Bob"<<endl;}else if(odd%4==2) cout<<"Bob"<<endl;else if(odd%4==3){cout<<"Alice"<<endl;}} signed main() {//ios;int T;cin>>T;while(T--)solve();return 0; }

I. Invoker

思路:明顯想到要充分利用前一個(gè)指令的三個(gè)字母,才用dp記錄的方式。
相當(dāng)于只能儲(chǔ)存3個(gè)字母,可打表記錄。
設(shè)計(jì)狀態(tài):dp[i][j]表示字母i對(duì)應(yīng)命令的第j種排列方式。
初始化:第一個(gè)字母固定需要三個(gè)命令字符
狀態(tài)轉(zhuǎn)移:dp[i][j]=min(dp[i][j],dp[i-1][g]+dis(mp[a[s[i-1]]][g],mp[a[s[i]]][j]));

#include<bits/stdc++.h> #define int long long #define endl '\n' #define For(i,a,b) for(i=(a);i<=(b);++i) #define ios (ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)) using namespace std; const int N=405; const int inf=1e18; const int mod=998244353; int n,dp[100005][6]; //第i個(gè)字母對(duì)應(yīng)第j種排序方式的最小字符數(shù) string s; string mp[10][6]={{"QQQ","QQQ","QQQ","QQQ","QQQ","QQQ"},{"QQW","QWQ","QQW","QWQ","WQQ","WQQ"},{"QQE","QEQ","QQE","QEQ","EQQ","EQQ"},{"WWW","WWW","WWW","WWW","WWW","WWW"},{"QWW","QWW","WQW","WWQ","WQW","WWQ"},{"WWE","WEW","WWE","WEW","EWW","EWW"},{"EEE","EEE","EEE","EEE","EEE","EEE"},{"QEE","QEE","EQE","EEQ","EQE","EEQ"},{"WEE","WEE","EWE","EEW","EWE","EEW"},{"QWE","QEW","WQE","WEQ","EQW","EWQ"}}; map<char,int>a; int dis(string s1,string s2) {if(s1==s2) return 0;if(s1[1]==s2[0]&&s1[2]==s2[1]) return 1;else if(s1[2]==s2[0]) return 2;else return 3; } void solve() {a['Y']=0,a['V']=1,a['G']=2,a['C']=3,a['X']=4;a['Z']=5,a['T']=6,a['F']=7,a['D']=8,a['B']=9;cin>>s;n=s.length();s=" "+s;for(int i=0;i<=n;i++) for(int j=0;j<6;j++) dp[i][j]=inf;for(int i=0;i<6;i++) dp[1][i]=3;for(int i=2;i<=n;i++){for(int j=0;j<6;j++){for(int g=0;g<6;g++){dp[i][j]=min(dp[i][j],dp[i-1][g]+dis(mp[a[s[i-1]]][g],mp[a[s[i]]][j]));}}}int ans=inf;for(int i=0;i<6;i++) ans=min(ans,dp[n][i]);cout<<ans+n<<endl; } signed main() {//ios;//int T;cin>>T;//while(T--)solve();return 0; }

總結(jié)

以上是生活随笔為你收集整理的打表+dp思维+博弈的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。