2050 Programming Competition
1006 冰水挑战
相似题目推荐
dp[i][j] 代表前i个挑战,选择了j个,最大的体力值是多少
#include <bits/stdc++.h>
#define mem(ar,num) memset(ar,num,sizeof(ar))
#define me(ar) memset(ar,0,sizeof(ar))
#define lowbit(x) (x&(-x))
#define Pb push_back
#define FI first
#define SE second
#define rep(i,a,n) for (int i=a;i<n;i++)
#define per(i,a,n) for (int i=n-1;i>=a;i--)
#define IOS ios::sync_with_stdio(false)
#define DEBUG cout<<endl<<"DEBUG"<<endl;
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
const int prime = 999983;
const int INF = 0x7FFFFFFF;
const LL INFF =0x7FFFFFFFFFFFFFFF;
const double pi = acos(-1.0);
const double inf = 1e18;
const double eps = 1e-6;
const LL mod = 1e9 + 7;
LL qpow(LL a,LL b){LL s=1;while(b>0){if(b&1)s=s*a%mod;a=a*a%mod;b>>=1;}return s;}
LL gcd(LL a,LL b) {return b?gcd(b,a%b):a;}
int dr[2][4] = {1,-1,0,0,0,0,-1,1};
typedef pair<int,int> P;
const int maxn = 1e3+10;
LL dp[maxn][maxn];// 代表现在到了第i个,完成了j个,体力的最大值
LL a[maxn],b[maxn],c[maxn];
int main(void)
{
int T;cin>>T;
while(T--){
int n,C;cin>>n>>C;
dp[0][0] = C;
for(int i = 1;i <= n; ++i){
scanf("%lld%lld%lld",&a[i],&b[i],&c[i]);
for(int j = 0;j <= i; ++j){
// dp[i][j] <- dp[i-1][j-1] + 选第i个
// dp[i][j] <- dp[i-1][j] + 不选第i个
dp[i][j] = 0;
if(dp[i-1][j] > 0)
dp[i][j] = dp[i-1][j]+c[i];
if(min(dp[i-1][j-1],b[i])> a[i]){
dp[i][j] = max(dp[i][j],min(dp[i-1][j-1],b[i])-a[i]+c[i]);
}
}
}
for(int i = n;i >= 0; --i)
if(dp[n][i] > 0){
printf("%d\n", i);
break;
}
}
return 0;
}
1005 球赛
dp[i][j][k] 代表已经打了i次比赛,比分为j:k 时的进行的局数最多是多少
这道题还有就是将状态压缩
例如10:10 和9:9 状态相同,这样j,k 的取值范围[0:10]
选择dp[i][j][k] 递推下面的状态是容易的,因为往下只有两个状态,而如果你知道j,k不太容易得知之前的状态
#include <bits/stdc++.h>
#define mem(ar,num) memset(ar,num,sizeof(ar))
#define me(ar) memset(ar,0,sizeof(ar))
#define lowbit(x) (x&(-x))
#define Pb push_back
#define FI first
#define SE second
#define rep(i,a,n) for (int i=a;i<n;i++)
#define per(i,a,n) for (int i=n-1;i>=a;i--)
#define IOS ios::sync_with_stdio(false)
#define DEBUG cout<<endl<<"DEBUG"<<endl;
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
const int prime = 999983;
const int INF = 0x7FFFFFFF;
const LL INFF =0x7FFFFFFFFFFFFFFF;
const double pi = acos(-1.0);
const double inf = 1e18;
const double eps = 1e-6;
const LL mod = 1e9 + 7;
LL qpow(LL a,LL b){LL s=1;while(b>0){if(b&1)s=s*a%mod;a=a*a%mod;b>>=1;}return s;}
LL gcd(LL a,LL b) {return b?gcd(b,a%b):a;}
int dr[2][4] = {1,-1,0,0,0,0,-1,1};
typedef pair<int,int> P;
const int maxn = 1e4+10;
int dp[maxn][11][11];// dp[i][j][k] 代表进行了i次赛,当前比分是j:k,最多完成了多少局
// 状态转移; dp[i][j][k]
// dp[i][j][k] = 转移,到i+1,
// A dp[i][j][k] 转移到 dp[i][j+1][k]
// B dp[i][j][k] 转移到 dp[i][j][k+1]
// ? 都可以转移
//
// 根据入度,出度选择我为人人还是人人为我型,判断哪一种更容易转移状态,我为人人需要提前将所有的状态初始化
char ar[maxn];
inline void chkmx(int &a,int b){
a = a<b?b:a;
}
int main(void)
{
int T;cin>>T;
while(T--){
scanf("%s",ar+1);
int n = strlen(ar+1);
memset(dp,-1,sizeof(dp));
dp[0][0][0] = 0;
for(int i = 0;i < n; ++i){
for(int j = 0;j <= 10; ++j){
for(int k = 0;k <= 10; ++k){
if(dp[i][j][k] == -1) continue;
if(ar[i+1] != 'B'){
int x = j+1;
int y = k;
int p = 0;
if(x == 11) x = 0,y = 0,p = 1;
if(x == 10 && y == 10)
x = 9,y = 9;
chkmx(dp[i+1][x][y],dp[i][j][k]+p);
}
if(ar[i+1] != 'A'){
int x = j;
int y = k+1;
int p = 0;
if(y == 11) x = 0,y = 0,p = 1;
if(x == 10&&y == 10)
x = 9,y = 9;
chkmx(dp[i+1][x][y],dp[i][j][k]+p);
}
}
}
}
int ans = 0;
for(int j = 0;j <= 10; ++j)
for(int k = 0;k <= 10; ++k)
ans = max(ans,dp[n][j][k]);
printf("%d\n",ans);
}
return 0;
}