dp练习
Posted babydragon
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了dp练习相关的知识,希望对你有一定的参考价值。
1013 Battle Over Cities
原来的图不一定连通,所以dfs统计连通块的时候要遍历所有的点。
pta总是有一些奇怪的边缘数据,
code
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<queue>
#include<cmath>
#include<map>
#include<stack>
#include<set>
#include<bitset>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> pii;
#define pb(x) push_back(x)
#define cls(x, val) memset(x, val, sizeof(x))
#define fi first
#define se second
#define mp(x, y) make_pair(x, y)
#define inc(i, l, r) for(int i=l; i<=r; i++)
const int inf = 0x3f3f3f3f;
const int maxn = 1000+10;
vector<int> G[maxn];
int n, m, k;
int del[maxn];
bool vis[maxn];
int ans[maxn];
int no;
void dfs(int u, int p)
vis[u] = true;
for(int i=0; i<G[u].size(); i++)
int v = G[u][i];
if(v == p || v==no||vis[v]) continue;
dfs(v, u);
int main()
ios::sync_with_stdio(false);
cin>>n>>m>>k;
int u, v;
for(int i=1; i<=m; i++)
cin>>u>>v;
G[u].push_back(v), G[v].push_back(u);
for(int i=1; i<=k; i++)
cin>>del[i];
int tot = 0;
no = del[i];
cls(vis, 0);
for(int j=1; j<=n; j++)
if(j == del[i]) continue;
if(!vis[j])
tot++;
dfs(j, -1);
ans[i] = tot-1;
for(int i=1; i<=k; i++) cout<<ans[i]<<endl;
return 0;
unidirectional TSP
记录移动状态的dp问题,还算比较的常规
求一条路径最短的矩阵路径,若权重相同则要使行序的字典序最小。
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<queue>
#include<cmath>
#include<map>
#include<stack>
#include<set>
#include<bitset>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> pii;
#define pb(x) push_back(x)
#define cls(x, val) memset(x, val, sizeof(x))
#define fi first
#define se second
#define mp(x, y) make_pair(x, y)
#define inc(i, l, r) for(int i=l; i<=r; i++)
const int inf = 0x3f3f3f3f;
const int maxn = 2000+10;
int num[15][105];
int dp[15][105];
int nex[15][105];
int n, m;
int main()
ios::sync_with_stdio(false);
while(~scanf("%d%d", &n, &m))
for(int i=1; i<=n; i++)
for(int j=1; j<=m; j++)
scanf("%d", &num[i][j]);
dp[i][j] = inf;
int ans = inf;
for(int col=m; col>=1; col--)
for(int row=1; row<=n; row++)
if(col == m) dp[row][col] = num[row][col];
else
int to[3] = row-1, row, row+1;
if(row == n) to[2] = 1;
if(row==1) to[0] = n;
sort(to, to+3);
for(int j=0; j<3; j++)
int temp = dp[to[j]][col+1]+num[row][col];
if(temp<dp[row][col])
dp[row][col] = temp;
nex[row][col] = to[j];
int mi = inf;
int first = -1;
for(int i=1; i<=n; i++)
if(dp[i][1]<mi)
mi = dp[i][1];
first = i;
int j=1;
for(int i=first; j<=m; j++)
printf("%d%c", i, j==m?'\n':' ');
i = nex[i][j];
printf("%d\n", mi);
return 0;
The lightning system
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<queue>
#include<cmath>
#include<map>
#include<stack>
#include<set>
#include<bitset>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> pii;
#define pb(x) push_back(x)
#define cls(x, val) memset(x, val, sizeof(x))
#define fi first
#define se second
#define mp(x, y) make_pair(x, y)
#define inc(i, l, r) for(int i=l; i<=r; i++)
const int inf = 0x3f3f3f3f;
const int maxn = 1000+10;
struct Node
int v, k, c, l;
bool operator < (const Node &b) const
return v<b.v;
node[maxn];
int n;
int dp[maxn];
int pre[maxn];
int main()
ios::sync_with_stdio(false);
while(cin>>n&&n)
for(int i=1; i<=n; i++)
cin>>node[i].v>>node[i].k>>node[i].c>>node[i].l;
//pre[i] = pre[i-1]+node[i].l;
sort(node+1, node+1+n);
pre[0] = 0;
for(int i=1; i<=n; i++) dp[i] = inf, pre[i] = pre[i-1]+node[i].l;
dp[1] = node[1].l*node[1].c+node[1].k;
dp[0] = 0;
for(int i=2; i<=n; i++)
for(int j=0; j<i; j++)
dp[i] = min(dp[i], dp[j]+(pre[i]-pre[j])*node[i].c+node[i].k);
cout<<dp[n]<<endl;
return 0;
jin ge jin qu(01背包)
条件有点唬人导致不敢做背包
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<queue>
#include<cmath>
#include<map>
#include<stack>
#include<set>
#include<bitset>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> pii;
#define pb(x) push_back(x)
#define cls(x, val) memset(x, val, sizeof(x))
#define fi first
#define se second
#define mp(x, y) make_pair(x, y)
#define inc(i, l, r) for(int i=l; i<=r; i++)
const int inf = 0x3f3f3f3f;
const int maxn = 180*50+678+10;
int dp[maxn];
int n;
int a[55];
int remain;
int main()
ios::sync_with_stdio(false);
int _;
cin>>_;
int kase = 1;
while(_--)
cin>>n>>remain;
int tot = 0;
for(int i=1; i<=n; i++) cin>>a[i], tot+=a[i];
for(int i=1; i<=remain; i++) dp[i] = -1;
dp[0] = 0;
for(int i=1; i<=n; i++)
for(int v=remain-1; v>=a[i]; v--)
if(dp[v-a[i]]>=0)
dp[v] = max(dp[v], dp[v-a[i]]+1);
int mx = -1;
int last = -1;
for(int i=remain-1; i>=0; i--)
if(mx<dp[i])
mx = dp[i];
last = i;
cout<<"Case "<<kase++<<": "<<mx+1<<" "<<last+678<<endl;
return 0;
矩阵的链乘(区间dp)
将问题转化为n-1矩阵的相乘
时间复杂度是\(O(n^3)\)
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<queue>
#include<cmath>
#include<map>
#include<stack>
#include<set>
#include<bitset>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> pii;
#define pb(x) push_back(x)
#define cls(x, val) memset(x, val, sizeof(x))
#define fi first
#define se second
#define mp(x, y) make_pair(x, y)
#define inc(i, l, r) for(int i=l; i<=r; i++)
const int inf = 0x3f3f3f3f;
const int maxn = 100+10;
int a[maxn];
int dp[maxn][maxn];
int n;
struct Matrix
int x, y;
node[maxn];
int main()
ios::sync_with_stdio(false);
while(cin>>n)
for(int i=1; i<=n; i++) cin>>a[i];
node[1].x=a[1] ,node[1].y=a[2];
for(int i=2; i<=n-1; i++)
node[i].x=a[i], node[i].y=a[i+1];
cls(dp, 0x3f);
for(int i=1; i<=n-2; i++)
dp[i][i+1] = node[i].x*node[i].y*node[i+1].y;
for(int i=1; i<=n-1; i++) dp[i][i] = 0;
for(int l=3; l<=n-1; l++)
for(int i=1; i<=n-l+1; i++)
int j=i+l-1;
for(int k=i; k<=j; k++)
//cout<<i<<" "<<k<<" "<<j<<endl;
if(dp[i][k]!=inf&&dp[k+1][j]!=inf)
dp[i][j] = min(dp[i][j], dp[i][k]+dp[k+1][j]+node[i].x*node[k].y*node[j].y);
//cout<<dp[1][4]<<endl;
cout<<dp[1][n-1]<<endl;
return 0;
以上是关于dp练习的主要内容,如果未能解决你的问题,请参考以下文章