社区讨论

Why正着DP是错的

P11188「KDOI-10」商店砍价参与者 3已保存回复 7

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
7 条
当前快照
1 份
快照标识符
@mhj3c1cm
此快照首次捕获于
2025/11/03 20:02
4 个月前
此快照最后确认于
2025/11/03 20:02
4 个月前
查看原帖
CPP
#include <bits/stdc++.h>
using namespace std;

long long dp[100010][10];//前i个数字,用了j个单连的最小花费 j<=6时才可能是minn 
long long num[100010][10];//当前坐标下的dp用的数字是啥 
long long v[10];
long long a[100010],n;
string T;

int weishu(long long k){
	int sum=0;
	while(k){
		k/=10;
		sum++;
	}
	return sum;
}

int main(){
	long long c;
	ios::sync_with_stdio(0);
	cin.tie(0),cout.tie(0);
	long long _;
	cin >> c >> _;
	while(_--){
		memset(dp,0,sizeof dp);
		memset(num,0,sizeof num);
		memset(a,0,sizeof a);
		memset(v,0,sizeof v);T="";
		cin >> T;n=0;
		for(long long i=0;i<=T.size()-1;i++) a[++n]=T[i]-'0';
		for(long long i=1;i<=9;i++) cin >> v[i];
		for(long long i=1;i<=n;i++){
			for(long long j=0;j<=7;j++){
				dp[i][j]=dp[i-1][j]+v[a[i]];
				num[i][j]=num[i-1][j];
			}
			for(long long j=1;j<=7;j++){//用一位会组成多少位 
				if(i<j)continue;
				long long x=dp[i-1][j-1]-num[i-1][j-1]+num[i-1][j-1]*10+a[i];
				if(x<=dp[i][j] or weishu(num[i][j])!=j){
					dp[i][j]=x;
					num[i][j]=num[i-1][j-1]*10+a[i];
				}
			}
		}
		long long minn=1e18;
		for(long long j=0;j<=7;j++){
			minn=min(minn,dp[n][j]);
		}
		cout << minn << "\n";
	}
	
	
	
	return 0;
}
36 : https://www.luogu.com.cn/record/238499074 看到有人说正着DP是错的,有人可以解释一下吗(蒟蒻求打捞帮蒟蒻)

回复

7 条回复,欢迎继续交流。

正在加载回复...