随笔- 16  文章- 0  评论- 0  阅读- 589 

B.好伙计猜拳

题目链接👈

题目描述🥰

题目思路😀

这个题目初看就是一个很典型的动态规划问题,但是状态的表示在我看来也是比较巧妙的,所以在比赛的过程中也是没有用动态规划解出这道题😇

动态规划主要是状态表示和状态的转移方程

状态表示:

  1. 用dp[i][0]表示在第i个记录没有进行交换的情况下使前i个记录合法的最小代价
  2. 用dp[i][1]表示在第i个记录进行了交换的情况下使前i个记录合法的最小代价

状态转移方程:(1<=i<=n,1<=j<i )

  1.    a[j]<=a[i] && b[j]<=b[i](两个已经符合递增的规则)
    1.  所以当第j个记录没有交换的情况下,第i条记录也不用进行交换,只需要删除两个记录之间的记录。dp[i][0]=min(dp[i][0],dp[j][0]+c1*(i-j-1))
    2.  当第j个记录已经交换的情况下,第i条记录也需要进行交换,与此同时,也需要删除两个记录之间的记录。dp[i][1]=min(dp[i][1],dp[j][1]+c2+c1*(i-j-1))
  2.    a[i]>=b[j] && b[i]>=a[j](两个在任意一个交换后即可符合递增的规则)

    1. 在第j个记录交换的情况下,第i条记录就不用进行交换,所以也只需要删除两个记录之间的记录。dp[i][0]=min(dp[i][0],dp[j][1]+c1*(i-j-1));
    2.  当第j个记录没有交换的情况下,第i条记录需要进行交换,与此同时,也需要删除两个记录之间的记录。dp[i][1]=min(dp[i][1],dp[j][0]+c2+c1*(i-j-1));

最重要的是需要对于边界的处理:为了保证最后的序列的整体合法,所以我们可以加一个一定在最后面的记录。

AC代码🧠

// Problem: 好伙计猜拳
// Contest: NowCoder
// URL: https://ac.nowcoder.com/acm/contest/95338/B
// Memory Limit: 512 MB
// Time Limit: 2000 ms
// 
// Powered by CP Editor (https://cpeditor.org)

#include <bits/stdc++.h>

#define dev1(a) cout << #a << '=' << a << endl;
#define dev2(a, b) cout << #a << " = " << a << "  " << #b << " = " << b << endl;
#define dev3(a, b, c) cout << #a << " = " << a << "  " << #b << " = " << b << "  " << #c << " = " << c << endl;
#define dev4(a, b, c, d) cout << #a << " = " << a << "  " << #b << " = " << b << "  " << #c << " = " << c << "  " << #d << " = " << d << endl;
#define dev5(a, b, c, d, e) cout << #a << " = " << a << "  " << #b << " = " << b << "  " << #c << " = " << c << "  " << #d << " = " << d << "  " << #e << " = " << e << endl;
#define vec(a)                         \
    for (int i = 0; i < a.size(); i++) \
        cout << a[i] << ' ';           \
    cout << endl;
#define darr(a, _i, _n)               \
    cout << #a << ':';                \
    for (int ij = _i; ij <= _n; ij++) \
        cout << a[ij] << ' ';         \
    cout << endl;           
#define cin(a,n)           \
     for(int i=0;i<n;i++) \
      cin>>a[i];          
#define endl "\n"
#define pow pim
int pim(int a,int k)
{
    int res=1;
    if(a==0)return 0;
    while(k) 
    {
        if(k&1)res=(int)res*a;
        k>>=1;
        a=(int)a*a;
    }
    return res;
}
#define fi first
#define se second
#define caseT \
    int T;    \
    cin >> T; \
    while (T--)
#define int long long
// #define int __int128

using namespace std;

typedef long long LL;
typedef unsigned long long ULL;
typedef pair<int, int> PII;
typedef pair<LL, LL> PLL;

const double PI = acos(-1.0);
const int INF = 0x3f3f3f3f;
const int MOD = 99999999;

// const int N = ;
int gcd(int a, int b)
{
    return b ? gcd(b, a % b) : a;
}
 
int lcm(int a, int b)
{
    return a * b / gcd(a, b);
}
inline int read()
{
    char c=getchar();int x=0,f=1;
    while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
    while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
    return x*f;
}
void solve()
{
	int n,c1,c2;
	cin>>n>>c1>>c2;
	n++;
	vector<int>a(n+1),b(n+1);
	for(int i=1;i<n;i++)cin>>a[i]>>b[i];
	//要设置一个来保证最终的序列合法
	a[n]=b[n]=1e9;
	vector<vector<int>>dp(n + 1, vector<int> (2));
	// dp[i][0]表示前i条记录在第i条记录没有交换的条件下需要的最小代价
	//定义边界
	for(int i=1;i<=n;i++)
		for(int j=0;j<2;j++)
		      dp[i][j]=1e18;
     for(int i=1;i<=n;i++)
      for(int j=i-1;j>=0;j--)
      {
      	  if(a[j]<=a[i]&&b[j]<=b[i]) 
      	  {
      	  	 dp[i][0]=min(dp[i][0],dp[j][0]+c1*(i-j-1));
      	  	 //如果说第j条的记录已经交换过,为了维持这个序列的合法性,那么i记录也要进行交换,同时删除两个之间的记录
      	  	 dp[i][1]=min(dp[i][1],dp[j][1]+c2+c1*(i-j-1));
      	  }
      	  if(a[i]>=b[j]&&b[i]>=a[j])
      	  {
      	  	//因为现在的情况已经反了,所以在j已经交换了的情况下i不用交换,代价就是删除两个记录中间的记录的代价
      	  	  dp[i][0]=min(dp[i][0],dp[j][1]+c1*(i-j-1));
      	  	  //因为现在的情况已经反了,而且j还没进行交换,所以i就需要进行交换,代价就是交换第i条记录并删除两个之间的记录
      	  	  dp[i][1]=min(dp[i][1],dp[j][0]+c2+c1*(i-j-1));
      	  }
      }
      
      cout<<min(dp[n][0],dp[n][1])<<endl;
}

signed main()
{

    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
	caseT
    solve();
    return 0;
}
/*

*/

 

 posted on   熙玺  阅读(5)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探

Shu-How Zの小窝

Loading...
点击右上角即可分享
微信分享提示